├── .gitignore ├── .vs ├── ProjectSettings.json ├── VSWorkspaceState.json ├── slnx.sqlite ├── slnx.sqlite-journal └── tasks.vs.json ├── CMakeLists.txt ├── CMakeSettings.json ├── Doc ├── Project-Reference.md └── Project-Todo.md ├── LBClient ├── CMakeLists.txt ├── LBClient.vcxproj ├── LBClient.vcxproj.filters ├── LBClient.vcxproj.user └── Src │ ├── Cpp │ ├── LBClient.cpp │ ├── LBClientHandler.cpp │ └── LBTcpClient.cpp │ └── Inc │ ├── LBClient.h │ ├── LBClientHandler.h │ └── LBTcpClient.h ├── LBEngine.sln ├── LBServer ├── CMakeLists.txt ├── LBServer.vcxproj ├── LBServer.vcxproj.filters ├── LBServer.vcxproj.user └── Src │ ├── Cpp │ ├── LBAcceptor.cpp │ ├── LBFactory.cpp │ ├── LBGameObject.cpp │ ├── LBIOContext.cpp │ ├── LBLogProcessor.cpp │ ├── LBLogger.cpp │ ├── LBSendPool.cpp │ ├── LBSender.cpp │ ├── LBServer.cpp │ ├── LBSession.cpp │ ├── LBSocket.cpp │ ├── LBTcpHandler.cpp │ ├── LBTimer.cpp │ ├── LBUdpHandler.cpp │ ├── LBUdpObject.cpp │ └── LBUdpSession.cpp │ └── Inc │ ├── LBAcceptor.Inl │ ├── LBAcceptor.h │ ├── LBBoostConfig.h │ ├── LBConfig.Inl │ ├── LBConfig.h │ ├── LBError.h │ ├── LBFactory.Inl │ ├── LBFactory.h │ ├── LBGameObject.h │ ├── LBGameServer.Inl │ ├── LBGameServer.h │ ├── LBHandler.Inl │ ├── LBHandler.h │ ├── LBIOContext.Inl │ ├── LBIOContext.h │ ├── LBLogProcessor.Inl │ ├── LBLogProcessor.h │ ├── LBLogger.Inl │ ├── LBLogger.h │ ├── LBPacketHeader.h │ ├── LBSendPool.h │ ├── LBSender.Inl │ ├── LBSender.h │ ├── LBServer.h │ ├── LBSession.Inl │ ├── LBSession.h │ ├── LBShard.Inl │ ├── LBShard.h │ ├── LBShardObject.h │ ├── LBSocket.Inl │ ├── LBSocket.h │ ├── LBTcpHandler.h │ ├── LBTimer.Inl │ ├── LBTimer.h │ ├── LBUdpHandler.h │ ├── LBUdpObject.h │ └── LBUdpSession.h ├── LBUtility ├── CMakeLists.txt ├── LBUtility.vcxproj ├── LBUtility.vcxproj.filters ├── LBUtility.vcxproj.user └── Src │ ├── Cpp │ ├── LBBuffer.cpp │ ├── LBEncryption.cpp │ ├── LBLocker.cpp │ ├── LBTime.cpp │ └── LBUtility.cpp │ └── Inc │ ├── LBBuffer.h │ ├── LBCharBase.h │ ├── LBEncryption.h │ ├── LBFile.Inl │ ├── LBFile.h │ ├── LBLocker.h │ ├── LBPool.Inl │ ├── LBPool.h │ ├── LBProbability.Inl │ ├── LBProbability.h │ ├── LBQueue.Inl │ ├── LBQueue.h │ ├── LBRandom.Inl │ ├── LBRandom.h │ ├── LBString.Inl │ ├── LBString.h │ ├── LBTime.Inl │ ├── LBTime.h │ └── LBUtility.h ├── README(en).md ├── README.md └── TestServer ├── AppDefines.h ├── CMakeLists.txt ├── CTestServer.cpp ├── CTestServer.h ├── TestServer.vcxproj ├── TestServer.vcxproj.filters ├── TestServer.vcxproj.user └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 이 .gitignore 파일은 Microsoft(R) Visual Studio에서 자동으로 만들어졌습니다. 3 | ################################################################################ 4 | 5 | #TestFile 6 | /AppLayer 7 | 8 | # Prerequisites 9 | *.d 10 | 11 | # Compiled Object files 12 | *.slo 13 | *.lo 14 | *.o 15 | *.obj 16 | *.lik 17 | *.pdb 18 | *.exp 19 | 20 | # Precompiled Headers 21 | *.gch 22 | *.pch 23 | 24 | # Compiled Dynamic libraries 25 | *.so 26 | *.dylib 27 | *.dll 28 | 29 | # Fortran module files 30 | *.mod 31 | *.smod 32 | 33 | # Compiled Static libraries 34 | *.lai 35 | *.la 36 | *.a 37 | *.lib 38 | 39 | # Executables 40 | *.exe 41 | *.out 42 | *.app 43 | 44 | # Visual Studio 45 | /.vs/LBEngine/v15 46 | /Bin 47 | /Intermediate 48 | -------------------------------------------------------------------------------- /.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": "Linux-Debug" 3 | } -------------------------------------------------------------------------------- /.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [ 3 | "", 4 | "\\LBUtility", 5 | "\\LBUtility\\Src", 6 | "\\TestServer" 7 | ], 8 | "SelectedNode": "\\LBEngine.sln", 9 | "PreviewInSolutionExplorer": false 10 | } -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/.vs/slnx.sqlite -------------------------------------------------------------------------------- /.vs/slnx.sqlite-journal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/.vs/slnx.sqlite-journal -------------------------------------------------------------------------------- /.vs/tasks.vs.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.1", 3 | "tasks": [ 4 | { 5 | "taskName": "task-CMakeSettings", 6 | "appliesTo": "CMakeSettings.json", 7 | "type": "launch" 8 | }, 9 | { 10 | "taskName": "task-CMakeSettings", 11 | "appliesTo": "CMakeSettings.json", 12 | "type": "launch" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2) 2 | 3 | project(LBEngine) 4 | 5 | add_subdirectory(LBUtility) 6 | add_subdirectory(LBServer) 7 | add_subdirectory(TestServer) 8 | -------------------------------------------------------------------------------- /CMakeSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux-Debug", 5 | "generator": "Unix Makefiles", 6 | "remoteMachineName": "localhost", 7 | "configurationType": "Debug", 8 | "remoteCMakeListsRoot": "/mnt/c/Users/user/source/repos/${workspaceHash}/install/${name}", 9 | "cmakeExecutable": "/mnt/c/Users/user/cmake-3.8.2/Bin", 10 | "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", 11 | "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", 12 | "remoteBuildRoot": "/mnt/c/Users/user/source/repos/${workspaceHash}/build/${name}", 13 | "remoteInstallRoot": "/mnt/c/Users/user/source/repos/${workspaceHash}/install/${name}", 14 | "remoteCopySources": true, 15 | "remoteCopySourcesOutputVerbosity": "Normal", 16 | "remoteCopySourcesConcurrentCopies": "10", 17 | "remoteCopySourcesMethod": "rsync", 18 | "remoteCopySourcesExclusionList": [ 19 | ".vs", 20 | ".git" 21 | ], 22 | "rsyncCommandArgs": "-t --delete --delete-excluded", 23 | "remoteCopyBuildOutput": false, 24 | "cmakeCommandArgs": "", 25 | "buildCommandArgs": "", 26 | "ctestCommandArgs": "", 27 | "inheritEnvironments": [ 28 | "linux_x64" 29 | ] 30 | }, 31 | { 32 | "name": "Linux-Release", 33 | "generator": "Unix Makefiles", 34 | "remoteMachineName": "${defaultRemoteMachineName}", 35 | "configurationType": "RelWithDebInfo", 36 | "remoteCMakeListsRoot": "/var/tmp/src/${workspaceHash}/${name}", 37 | "cmakeExecutable": "/usr/local/bin/cmake", 38 | "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", 39 | "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", 40 | "remoteBuildRoot": "/var/tmp/build/${workspaceHash}/build/${name}", 41 | "remoteInstallRoot": "/var/tmp/build/${workspaceHash}/install/${name}", 42 | "remoteCopySources": true, 43 | "remoteCopySourcesOutputVerbosity": "Normal", 44 | "remoteCopySourcesConcurrentCopies": "10", 45 | "remoteCopySourcesMethod": "rsync", 46 | "remoteCopySourcesExclusionList": [ 47 | ".vs", 48 | ".git" 49 | ], 50 | "rsyncCommandArgs": "-t --delete --delete-excluded", 51 | "remoteCopyBuildOutput": false, 52 | "cmakeCommandArgs": "", 53 | "buildCommandArgs": "", 54 | "ctestCommandArgs": "", 55 | "inheritEnvironments": [ 56 | "linux_x64" 57 | ] 58 | } 59 | ] 60 | } -------------------------------------------------------------------------------- /Doc/Project-Reference.md: -------------------------------------------------------------------------------- 1 | LBEngine Project Reference 2 | ================================ 3 | 4 | 1.etc 5 | ------------------------- 6 | 7 | -네트워크는 boost::asio 라이브러리를 기반으로 작성한다.(버전 1.70) 8 | -윈도우를 타겟으로 만들지만 추후에 리눅스 포팅을 대비하여 플랫폼 독립적인 코드를 작성한다. 9 | 10 | 2.CPP 11 | ------------------------- 12 | 13 | -템플릿 인자는 T를 붙이고, 일반 타입은 자유롭게 사용, 클래스 타입은 C를 사용한다. 14 | -클래스의 public는 m을 붙이고, protected는 _m, private는 __m을 붙인다. 15 | -enum은 E를 붙이고 내부 값은 e를 붙인다 16 | -지역변수는 a를 붙여 사용한다. 17 | -템플릿 이외에는 inline는 이용하지 않는다. 컴파일러의 최적화를 이용한다. 18 | (단 디버그모드에선 최적화를 사용하지 않는다.) 19 | -std::shared_ptr은 소유권 개념으로 사용한다. 같은 쓰레드 내에서는 복사를 하지 않는다.(이동, 레퍼런스로 전달) 20 | -DLL 라이브러리 사용시 static변수 사용에 유의한다.(상위, 하위 레이어 사이에서 한쪽에서만 생성하고 한쪽을 포인터, 레퍼런스로 사용한다.) 21 | 22 | Reference 23 | ------------------------- 24 | 25 | L1: [C++11 하이퍼 쓰레딩](https://eli.thegreenplace.net/2016/c11-threads-affinity-and-hyperthreading) 26 | L2: [프로세서 스케쥴링 이론](http://colomy.tistory.com/120) 27 | L3: [윈도우10 쓰레드 분배](http://www.hwbattle.com/bbs/board.php?bo_table=news&wr_id=70307) 28 | L4: [doxygen 매뉴얼](https://rinovation.tistory.com/77) 29 | L5: [SRWLock 구현](https://megayuchi.com/2017/06/25/srwlock-%EB%B9%A0%EB%A5%B8-%EC%84%B1%EB%8A%A5%EC%9D%98-%EB%B9%84%EA%B2%B0) 30 | L6: [std::allocator is deprecated in C++17](https://github.com/boostorg/beast/issues/1272) 31 | L7: [Warning C4251](https://mgun.tistory.com/508) 32 | L8: [[boost.asio] strand는 어떻게 동작하고 왜 사용해야 하는가?](http://blog.naver.com/PostView.nhn?blogId=njh0602&logNo=220715956896&parentCategoryNo=&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView) -------------------------------------------------------------------------------- /Doc/Project-Todo.md: -------------------------------------------------------------------------------- 1 | LBEngine Project TODO 2 | ================================ 3 | 4 | Desc : TODO에서는 구현이 필요한 내용을 적습니다. 5 | TODO에서 구현 완료시 Test로 내용을 올리고 테스트 완료시 Complete로 옮깁니다. 6 | 7 | TODO 8 | ------------------------- 9 | 10 | - [ ] ORM 기능 구현 11 | - [ ] Keep Alive 구현 12 | - [ ] 메모리 덤프 13 | - [ ] HTTP 14 | - [ ] 비동기 관련 기능 구현 15 | - [ ] 리눅스 포팅 16 | - [ ] C++/Cli 17 | - [ ] 향상된 락기능(싱글스레드 NoLock, 데드락 감지) 18 | - [ ] 클라이언트용 모듈(UDP) 19 | 20 | Test 21 | ------------------------- 22 | 23 | - [ ] 암호화 기능 구현 24 | - [ ] UDP 25 | 26 | Complete 27 | ------------------------- 28 | 29 | - [X] RWLock(std::shared_mutex) 30 | - [X] 파일 입출력 구현 31 | - [X] 랜덤, 확률 기능 구현 32 | - [X] LBServer 프로젝트 설정 33 | - [X] 소켓, Acceptor 34 | - [X] 자원관리(Factory등등) 35 | - [X] 세션 36 | - [X] 패킷 핸들링 37 | - [X] 게임 서버 메인 구조 구현 38 | - [X] 동적 버퍼 구현 39 | - [X] Send 메모리 관리 40 | - [X] 에러코드 구현 41 | - [X] 로그 기능 구현 42 | - [X] 클라이언트용 모듈 43 | - [X] 서버옵션 설정 기능 44 | 45 | Memo 46 | ------------------------- -------------------------------------------------------------------------------- /LBClient/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2) 2 | 3 | project(LBClient) 4 | 5 | set(CMAKE_CONFIGURATION_TYPES "Debug;Release" 6 | CACHE STRING "Configuration types" FORCE) 7 | 8 | add_library(LBClient SHARED 9 | Src/Cpp/LBClient.cpp 10 | Src/Cpp/LBClientHandler.cpp 11 | Src/Cpp/LBTcpClient.cpp 12 | Src/Inc/LBClient.h 13 | Src/Inc/LBClientHandler.h 14 | Src/Inc/LBTcpClient.h 15 | ) 16 | # Output file name 17 | set_target_properties(LBClient 18 | PROPERTIES 19 | OUTPUT_NAME_DEBUG LBClientD_x64 20 | OUTPUT_NAME_RELEASE LBClient_x64 21 | ) 22 | 23 | # Additional include directories 24 | set_property(TARGET LBClient 25 | APPEND PROPERTY INCLUDE_DIRECTORIES 26 | $<$: 27 | C:\boost_1_70_0> 28 | $<$: 29 | C:\boost_1_70_0> 30 | ) 31 | 32 | # Preprocessor definitions 33 | target_compile_definitions(LBClient PRIVATE 34 | $<$:_UNICODE;X64;_DEBUG;_CONSOLE> 35 | $<$:_UNICODE;X64;NDEBUG;_CONSOLE> 36 | ) 37 | 38 | # SDL check 39 | target_compile_options(LBClient PRIVATE 40 | "$<$:/sdl>" 41 | "$<$:/sdl>" 42 | ) 43 | 44 | # Minimal rebuild 45 | if (MSVC) 46 | target_compile_options(LBClient PRIVATE 47 | "$<$:/Gm->" 48 | "$<$:/Gm->" 49 | ) 50 | endif () 51 | 52 | # Precompiled header files 53 | if (MSVC) 54 | target_compile_options(LBClient PRIVATE 55 | "" 56 | ) 57 | endif () 58 | -------------------------------------------------------------------------------- /LBClient/LBClient.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3} 24 | LBClient 25 | 10.0.17763.0 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v141 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v141 38 | true 39 | Unicode 40 | 41 | 42 | DynamicLibrary 43 | true 44 | v141 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v141 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | $(SolutionDir)LBUtility\Src\Inc;$(SolutionDir)LBServer\Src\Inc;$(ProjectDir)Src\Inc;$(IncludePath) 74 | C:\boost_1_70_0\stage\lib;$(SolutionDir)Bin;$(LibraryPath) 75 | $(SolutionDir)Bin\ 76 | $(SolutionDir)Intermediate\$(ProjectName)\ 77 | $(ProjectName)D_$(PlatformTarget) 78 | 79 | 80 | $(SolutionDir)LBUtility\Src\Inc;$(SolutionDir)LBServer\Src\Inc;$(ProjectDir)Src\Inc;$(IncludePath) 81 | C:\boost_1_70_0\stage\lib;$(SolutionDir)Bin;$(LibraryPath) 82 | $(SolutionDir)Bin\ 83 | $(SolutionDir)Intermediate\$(ProjectName)\ 84 | $(ProjectName)_$(PlatformTarget) 85 | 86 | 87 | $(SolutionDir)LBUtility\Src\Inc;$(SolutionDir)LBServer\Src\Inc;$(ProjectDir)Src\Inc;$(IncludePath) 88 | C:\boost_1_70_0\stage\lib;$(SolutionDir)Bin;$(LibraryPath) 89 | $(SolutionDir)Bin\ 90 | $(SolutionDir)Intermediate\$(ProjectName)\ 91 | $(ProjectName)D_$(PlatformTarget) 92 | 93 | 94 | $(SolutionDir)LBUtility\Src\Inc;$(SolutionDir)LBServer\Src\Inc;$(ProjectDir)Src\Inc;$(IncludePath) 95 | C:\boost_1_70_0\stage\lib;$(SolutionDir)Bin;$(LibraryPath) 96 | $(SolutionDir)Bin\ 97 | $(SolutionDir)Intermediate\$(ProjectName)\ 98 | $(ProjectName)_$(PlatformTarget) 99 | 100 | 101 | 102 | Level3 103 | Disabled 104 | true 105 | true 106 | C:\boost_1_70_0; 107 | X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 108 | 109 | 110 | 111 | 112 | Level3 113 | Disabled 114 | true 115 | true 116 | C:\boost_1_70_0; 117 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | 119 | 120 | 121 | 122 | Level3 123 | MaxSpeed 124 | true 125 | true 126 | true 127 | true 128 | C:\boost_1_70_0; 129 | X86;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | 131 | 132 | true 133 | true 134 | 135 | 136 | 137 | 138 | Level3 139 | MaxSpeed 140 | true 141 | true 142 | true 143 | true 144 | C:\boost_1_70_0; 145 | X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 146 | 147 | 148 | true 149 | true 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /LBClient/LBClient.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {b2c36a41-9549-455a-b47f-687191507b19} 6 | 7 | 8 | {22956de3-9ae5-4b92-aeaf-9d61401e6718} 9 | 10 | 11 | 12 | 13 | Core 14 | 15 | 16 | Client 17 | 18 | 19 | Client 20 | 21 | 22 | 23 | 24 | Core 25 | 26 | 27 | Client 28 | 29 | 30 | Client 31 | 32 | 33 | -------------------------------------------------------------------------------- /LBClient/LBClient.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /LBClient/Src/Cpp/LBClient.cpp: -------------------------------------------------------------------------------- 1 | #include "LBClient.h" 2 | 3 | namespace LBNet 4 | { 5 | constexpr Version GetLBCVersion() 6 | { 7 | return 20191124u; 8 | } 9 | } -------------------------------------------------------------------------------- /LBClient/Src/Cpp/LBClientHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "LBClientHandler.h" 2 | 3 | namespace LBNet 4 | { 5 | CClientHandler CClientHandler::__mSingleton; 6 | 7 | CClientHandler& CClientHandler::Instance() 8 | { 9 | return __mSingleton; 10 | } 11 | } -------------------------------------------------------------------------------- /LBClient/Src/Cpp/LBTcpClient.cpp: -------------------------------------------------------------------------------- 1 | #include "LBTcpClient.h" 2 | #include "LBEncryption.h" 3 | 4 | namespace LBNet 5 | { 6 | CTcpClient::CTcpClient() : __mSocket(), __mBuffer(eSzPacketMax), 7 | __mState(EState::eDisconnected), __mLastError(0) 8 | { 9 | __mBuffer.Clear(); 10 | } 11 | 12 | CTcpClient::CTcpClient(Size pBufSize) : __mSocket(), __mBuffer(pBufSize), 13 | __mState(EState::eDisconnected), __mLastError(0) 14 | { 15 | __mBuffer.Clear(); 16 | } 17 | 18 | ErrCode CTcpClient::Connect(const char* pIp, unsigned short pPort) 19 | { 20 | ErrCode aResult = __mSocket.Connect(pIp, pPort); 21 | 22 | if (aResult == 0) 23 | __mState = EState::eConnected; 24 | 25 | return aResult; 26 | } 27 | 28 | ErrCode CTcpClient::Receive(bool pIsZeroRecv) 29 | { 30 | Size aSize = __mBuffer.GetUsableSize(); 31 | 32 | if (aSize < eSzPacketMin || __mBuffer.GetBufferSize() < aSize) 33 | { 34 | SetDisconnect(eErrCodeSesBufferFull); 35 | return eErrCodeSesBufferFull; 36 | } 37 | 38 | if (pIsZeroRecv) 39 | aSize = 0; 40 | 41 | int aReceived = 0; 42 | char* aWritePtr = __mBuffer.GetWritePointer(); 43 | ErrCode aErr = __mSocket.Receive(aWritePtr, aSize, aReceived); 44 | if (aErr != 0) 45 | { 46 | SetDisconnect(aErr); 47 | return aErr; 48 | } 49 | 50 | if (aSize == 0 && !pIsZeroRecv) 51 | { 52 | SetDisconnect(eErrCodeSesDisconnected); 53 | return eErrCodeSesDisconnected; 54 | } 55 | 56 | if (!__mBuffer.OnPush(static_cast(aReceived))) 57 | { 58 | SetDisconnect(eErrCodeSesBufferFull); 59 | return eErrCodeSesBufferFull; 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | ErrCode CTcpClient::ProcessPacket() 66 | { 67 | if (__mState == EState::eDisconnected) 68 | return eErrCodeSesDisconnected; 69 | 70 | Size aSize = 0; 71 | ErrCode aResult = 0; 72 | char* aData = __mBuffer.Front(aSize, aResult); 73 | 74 | while (aData != nullptr && aResult == 0) 75 | { 76 | Size aEncryptHdSize = 0; 77 | if (CEncryptor::Instance() != nullptr) 78 | { 79 | aEncryptHdSize = CEncryptor::Instance()->GetHeaderSize(); 80 | aSize -= aEncryptHdSize; 81 | aResult = CEncryptor::Instance()->Decrypt(aData, aSize); 82 | 83 | if (aResult != 0) 84 | { 85 | SetDisconnect(aResult); 86 | return aResult; 87 | } 88 | } 89 | 90 | CPacketHeader* aHeader = reinterpret_cast(aData + aEncryptHdSize); 91 | aResult = CClientHandler::Instance().Process(aHeader->mMessage, aHeader, aSize); 92 | if (aResult != 0) 93 | break; 94 | 95 | aData = __mBuffer.Front(aSize, aResult); 96 | } 97 | 98 | if (aResult != 0) 99 | SetDisconnect(aResult); 100 | 101 | __mBuffer.Pop(); 102 | return aResult; 103 | } 104 | 105 | ErrCode CTcpClient::Send(void* pBuffer, int pSize) 106 | { 107 | int aSendSize = 0; 108 | ErrCode aResult = __mSocket.Send(pBuffer, pSize, aSendSize); 109 | 110 | if (aResult != 0 || aSendSize == 0) 111 | SetDisconnect(aResult); 112 | 113 | return aResult; 114 | } 115 | 116 | ErrCode CTcpClient::Send(SharedObject& pSender) 117 | { 118 | if (pSender == nullptr) 119 | return eErrCodeNullSender; 120 | 121 | LB_ASSERT(__mState == EState::eConnected, "Invalid!"); 122 | 123 | auto aSendPtr = pSender->GetSendPointer(); 124 | auto aSendSize = pSender->GetSendSize(); 125 | int aSendedSize = 0; 126 | 127 | if (aSendPtr == nullptr) 128 | return eErrCodeNullSender; 129 | 130 | ErrCode aResult = __mSocket.Send(aSendPtr, aSendSize, aSendedSize); 131 | if (aResult != 0 || aSendedSize == 0) 132 | SetDisconnect(aResult); 133 | 134 | return aResult; 135 | } 136 | 137 | ErrCode CTcpClient::Close() 138 | { 139 | if (__mState == EState::eDisconnected) 140 | return 0; 141 | 142 | return __mSocket.Close(); 143 | } 144 | 145 | ErrCode CTcpClient::SetDisconnect(ErrCode pErr) 146 | { 147 | __mLastError = pErr; 148 | return Close(); 149 | } 150 | 151 | CTcpClient::EState CTcpClient::GetState() const 152 | { 153 | return __mState; 154 | } 155 | 156 | ErrCode CTcpClient::GetLastError() const 157 | { 158 | return __mLastError; 159 | } 160 | } -------------------------------------------------------------------------------- /LBClient/Src/Inc/LBClient.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBClient/Src/Inc/LBClient.h -------------------------------------------------------------------------------- /LBClient/Src/Inc/LBClientHandler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBClient/Src/Inc/LBClientHandler.h -------------------------------------------------------------------------------- /LBClient/Src/Inc/LBTcpClient.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBClient/Src/Inc/LBTcpClient.h -------------------------------------------------------------------------------- /LBEngine.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2005 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LBUtility", "LBUtility\LBUtility.vcxproj", "{30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Doc", "Doc", "{1C487B5D-4CED-4AAF-BB96-DBC9B52477FA}" 9 | ProjectSection(SolutionItems) = preProject 10 | Doc\Project-Reference.md = Doc\Project-Reference.md 11 | Doc\Project-Todo.md = Doc\Project-Todo.md 12 | README(en).md = README(en).md 13 | README.md = README.md 14 | EndProjectSection 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LBServer", "LBServer\LBServer.vcxproj", "{69D9DDFA-1926-432C-9250-2B0D869E4F33}" 17 | ProjectSection(ProjectDependencies) = postProject 18 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A} = {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A} 19 | EndProjectSection 20 | EndProject 21 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LBClient", "LBClient\LBClient.vcxproj", "{D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}" 22 | ProjectSection(ProjectDependencies) = postProject 23 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A} = {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A} 24 | {69D9DDFA-1926-432C-9250-2B0D869E4F33} = {69D9DDFA-1926-432C-9250-2B0D869E4F33} 25 | EndProjectSection 26 | EndProject 27 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestServer", "TestServer\TestServer.vcxproj", "{F423E23D-3939-47D5-9910-F68CF018912A}" 28 | ProjectSection(ProjectDependencies) = postProject 29 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3} = {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3} 30 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A} = {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A} 31 | {69D9DDFA-1926-432C-9250-2B0D869E4F33} = {69D9DDFA-1926-432C-9250-2B0D869E4F33} 32 | EndProjectSection 33 | EndProject 34 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C15EC03F-7112-421E-AC9D-BB06233B8176}" 35 | ProjectSection(SolutionItems) = preProject 36 | CMakeLists.txt = CMakeLists.txt 37 | EndProjectSection 38 | EndProject 39 | Global 40 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 41 | Debug|x64 = Debug|x64 42 | Debug|x86 = Debug|x86 43 | Release|x64 = Release|x64 44 | Release|x86 = Release|x86 45 | EndGlobalSection 46 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 47 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}.Debug|x64.ActiveCfg = Debug|x64 48 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}.Debug|x64.Build.0 = Debug|x64 49 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}.Debug|x86.ActiveCfg = Debug|Win32 50 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}.Debug|x86.Build.0 = Debug|Win32 51 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}.Release|x64.ActiveCfg = Release|x64 52 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}.Release|x64.Build.0 = Release|x64 53 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}.Release|x86.ActiveCfg = Release|Win32 54 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A}.Release|x86.Build.0 = Release|Win32 55 | {69D9DDFA-1926-432C-9250-2B0D869E4F33}.Debug|x64.ActiveCfg = Debug|x64 56 | {69D9DDFA-1926-432C-9250-2B0D869E4F33}.Debug|x64.Build.0 = Debug|x64 57 | {69D9DDFA-1926-432C-9250-2B0D869E4F33}.Debug|x86.ActiveCfg = Debug|Win32 58 | {69D9DDFA-1926-432C-9250-2B0D869E4F33}.Debug|x86.Build.0 = Debug|Win32 59 | {69D9DDFA-1926-432C-9250-2B0D869E4F33}.Release|x64.ActiveCfg = Release|x64 60 | {69D9DDFA-1926-432C-9250-2B0D869E4F33}.Release|x64.Build.0 = Release|x64 61 | {69D9DDFA-1926-432C-9250-2B0D869E4F33}.Release|x86.ActiveCfg = Release|Win32 62 | {69D9DDFA-1926-432C-9250-2B0D869E4F33}.Release|x86.Build.0 = Release|Win32 63 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}.Debug|x64.ActiveCfg = Debug|x64 64 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}.Debug|x64.Build.0 = Debug|x64 65 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}.Debug|x86.ActiveCfg = Debug|Win32 66 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}.Debug|x86.Build.0 = Debug|Win32 67 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}.Release|x64.ActiveCfg = Release|x64 68 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}.Release|x64.Build.0 = Release|x64 69 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}.Release|x86.ActiveCfg = Release|Win32 70 | {D1EA27BE-DB6F-47F5-84BE-0EB4122299C3}.Release|x86.Build.0 = Release|Win32 71 | {F423E23D-3939-47D5-9910-F68CF018912A}.Debug|x64.ActiveCfg = Debug|x64 72 | {F423E23D-3939-47D5-9910-F68CF018912A}.Debug|x64.Build.0 = Debug|x64 73 | {F423E23D-3939-47D5-9910-F68CF018912A}.Debug|x86.ActiveCfg = Debug|Win32 74 | {F423E23D-3939-47D5-9910-F68CF018912A}.Debug|x86.Build.0 = Debug|Win32 75 | {F423E23D-3939-47D5-9910-F68CF018912A}.Release|x64.ActiveCfg = Release|x64 76 | {F423E23D-3939-47D5-9910-F68CF018912A}.Release|x64.Build.0 = Release|x64 77 | {F423E23D-3939-47D5-9910-F68CF018912A}.Release|x86.ActiveCfg = Release|Win32 78 | {F423E23D-3939-47D5-9910-F68CF018912A}.Release|x86.Build.0 = Release|Win32 79 | EndGlobalSection 80 | GlobalSection(SolutionProperties) = preSolution 81 | HideSolutionNode = FALSE 82 | EndGlobalSection 83 | GlobalSection(ExtensibilityGlobals) = postSolution 84 | SolutionGuid = {2D815737-CC26-4BC0-A511-DFC59CA98FD9} 85 | EndGlobalSection 86 | EndGlobal 87 | -------------------------------------------------------------------------------- /LBServer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2) 2 | 3 | project(LBServer) 4 | 5 | set(CMAKE_CONFIGURATION_TYPES "Debug;Release" 6 | CACHE STRING "Configuration types" FORCE) 7 | 8 | set(LBENGINE_OUT_DIRECTORY "/bin") 9 | 10 | # Compile options 11 | include(../Build/CMake/CompileOptions.cmake) 12 | 13 | INCLUDE_DIRECTORIES(Src/Inc) 14 | INCLUDE_DIRECTORIES(../LBUtility/Src/Inc) 15 | INCLUDE_DIRECTORIES(BOOST_DIRECTORY) 16 | 17 | # Source 18 | file(GLOB_RECURSE HEADERS 19 | ${CMAKE_CURRENT_SOURCE_DIR}/Src/Inc/*.h) 20 | 21 | file(GLOB_RECURSE SOURCES 22 | ${CMAKE_CURRENT_SOURCE_DIR}/Src/Cpp/*.cpp) 23 | 24 | add_library(LBServer SHARED 25 | ${SOURCES} 26 | ) 27 | 28 | # Set postfix by configuration 29 | if(CMAKE_CONFIGURATION_TYPES STREQUAL "Debug") 30 | set(CONFIGURATUON_POSTFIX "D") 31 | else(CMAKE_CONFIGURATION_TYPES STREQUAL "Release") 32 | set(CONFIGURATUON_POSTFIX "") 33 | endif() 34 | 35 | set(OUTPUT_FILE_NAME "LBServer${CONFIGURATUON_POSTFIX}_x64") 36 | 37 | # Preprocessor definitions 38 | target_compile_definitions(LBServer PRIVATE 39 | $<$:_UNICODE;X64;_DEBUG;_CONSOLE> 40 | $<$:_UNICODE;X64;NDEBUG;_CONSOLE> 41 | ) 42 | 43 | # SDL check 44 | if (MSVC) 45 | target_compile_options(TestServer PRIVATE 46 | "$<$:/sdl>" 47 | "$<$:/sdl>" 48 | ) 49 | endif () 50 | 51 | # Minimal rebuild 52 | if (MSVC) 53 | target_compile_options(LBServer PRIVATE 54 | "$<$:/Gm->" 55 | "$<$:/Gm->" 56 | ) 57 | endif () 58 | 59 | # Precompiled header files 60 | if (MSVC) 61 | target_compile_options(LBServer PRIVATE 62 | "" 63 | ) 64 | endif () -------------------------------------------------------------------------------- /LBServer/LBServer.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {69D9DDFA-1926-432C-9250-2B0D869E4F33} 24 | LBServer 25 | 10.0.17763.0 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v141 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v141 38 | true 39 | Unicode 40 | 41 | 42 | DynamicLibrary 43 | true 44 | v141 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v141 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | $(SolutionDir)Bin\ 74 | $(SolutionDir)Intermediate\$(ProjectName)\ 75 | $(ProjectName)D_$(PlatformTarget) 76 | $(ProjectDir)Src\Inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)LBUtility\Src\Inc 77 | $(ReferencePath) 78 | $(SolutionDir)Bin\;C:\boost_1_70_0\stage\lib;$(LibraryPath) 79 | 80 | 81 | $(SolutionDir)Bin\ 82 | $(SolutionDir)Intermediate\$(ProjectName)\ 83 | $(ProjectName)_$(PlatformTarget) 84 | $(ProjectDir)Src\Inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)LBUtility\Src\Inc 85 | $(ReferencePath) 86 | C:\boost_1_70_0\stage\lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 87 | 88 | 89 | $(SolutionDir)Bin\ 90 | $(SolutionDir)Intermediate\$(ProjectName)\ 91 | $(ProjectName)D_$(PlatformTarget) 92 | $(ProjectDir)Src\Inc;$(SolutionDir)LBUtility\Src\Inc;$(IncludePath) 93 | $(ReferencePath) 94 | C:\boost_1_70_0\stage\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;$(SolutionDir)Bin\ 95 | 96 | 97 | $(SolutionDir)Bin\ 98 | $(SolutionDir)Intermediate\$(ProjectName)\ 99 | $(ProjectName)_$(PlatformTarget) 100 | $(ReferencePath) 101 | $(ProjectDir)Src\Inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)LBUtility\Src\Inc 102 | C:\boost_1_70_0\stage\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 103 | 104 | 105 | 106 | Level4 107 | Disabled 108 | true 109 | true 110 | X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 111 | C:\boost_1_70_0; 112 | NotUsing 113 | LBServer.h 114 | stdcpp17 115 | Disabled 116 | 117 | 118 | %(AdditionalDependencies) 119 | 120 | 121 | 122 | 123 | Level4 124 | Disabled 125 | true 126 | true 127 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 128 | C:\boost_1_70_0; 129 | stdcpp17 130 | 131 | 132 | %(AdditionalDependencies) 133 | 134 | 135 | 136 | 137 | Level4 138 | MaxSpeed 139 | true 140 | true 141 | true 142 | true 143 | X86;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 144 | C:\boost_1_70_0; 145 | stdcpp17 146 | 147 | 148 | true 149 | true 150 | %(AdditionalDependencies) 151 | 152 | 153 | 154 | 155 | Level4 156 | MaxSpeed 157 | true 158 | true 159 | true 160 | true 161 | X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 162 | C:\boost_1_70_0; 163 | stdcpp17 164 | 165 | 166 | true 167 | true 168 | %(AdditionalDependencies) 169 | 170 | 171 | 172 | 173 | false 174 | false 175 | false 176 | false 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | false 190 | false 191 | false 192 | false 193 | 194 | 195 | false 196 | false 197 | false 198 | false 199 | 200 | 201 | 202 | 203 | 204 | false 205 | false 206 | false 207 | false 208 | 209 | 210 | 211 | false 212 | false 213 | false 214 | false 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | false 225 | false 226 | false 227 | false 228 | 229 | 230 | 231 | false 232 | false 233 | false 234 | false 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | false 244 | false 245 | false 246 | false 247 | 248 | 249 | false 250 | false 251 | false 252 | false 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | false 263 | false 264 | false 265 | false 266 | 267 | 268 | Document 269 | 270 | 271 | Document 272 | 273 | 274 | Document 275 | 276 | 277 | Document 278 | 279 | 280 | Document 281 | false 282 | false 283 | false 284 | false 285 | 286 | 287 | Document 288 | 289 | 290 | Document 291 | 292 | 293 | Document 294 | 295 | 296 | Document 297 | 298 | 299 | Document 300 | 301 | 302 | false 303 | false 304 | false 305 | false 306 | 307 | 308 | 309 | 310 | 311 | {30e01ddd-eaab-48ed-9171-e451c1a2ee3a} 312 | 313 | 314 | 315 | 316 | 317 | -------------------------------------------------------------------------------- /LBServer/LBServer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {6062b5c2-65b9-40c6-925a-daa4855cb789} 6 | 7 | 8 | {8f29d26b-e3f9-4caf-baee-7f4a6974a903} 9 | 10 | 11 | {3cf98dac-7698-4420-8e0e-48d8e8abf1ac} 12 | 13 | 14 | {9bb8621d-b467-4736-a795-3ffacf2affda} 15 | 16 | 17 | {8d32bace-8bbf-4f37-820f-e274744a1c63} 18 | 19 | 20 | {73b17993-1fbe-4d21-a0c2-fa1861b83e0d} 21 | 22 | 23 | {dc3cd230-3bf8-4e37-81a7-e0129f28403d} 24 | 25 | 26 | {f57c1fdc-92ef-46a4-8247-adc8ac138f5e} 27 | 28 | 29 | {e9cf8082-2842-4958-98df-4ade2369275c} 30 | 31 | 32 | {ba3ef4ff-27f2-467c-87ae-94261900dcbc} 33 | 34 | 35 | {10b36e78-5489-44b2-86a9-1f0f4dc605ec} 36 | 37 | 38 | {378cae39-555f-4a80-8364-1b71bf9bdd05} 39 | 40 | 41 | {a23ccf37-cd04-4ab0-b7c3-a3534549e7b7} 42 | 43 | 44 | {8f405ff4-47a3-4da4-8ab9-1e34636aaf16} 45 | 46 | 47 | {fa40986c-b673-47bc-a9ed-fbf59b4e6274} 48 | 49 | 50 | 51 | 52 | Core 53 | 54 | 55 | Memory 56 | 57 | 58 | Network\Session 59 | 60 | 61 | Network\Socket\Acceptor 62 | 63 | 64 | Network\Handler 65 | 66 | 67 | Network\Object 68 | 69 | 70 | Memory 71 | 72 | 73 | Network\Session 74 | 75 | 76 | Network\Shard 77 | 78 | 79 | Network\Server 80 | 81 | 82 | Network\Shard 83 | 84 | 85 | Network\Server 86 | 87 | 88 | Network\Shard 89 | 90 | 91 | Timer 92 | 93 | 94 | Memory\Send 95 | 96 | 97 | Memory\Send 98 | 99 | 100 | Memory\Send 101 | 102 | 103 | Core 104 | 105 | 106 | Network\NetworkIO 107 | 108 | 109 | Network\NetworkIO 110 | 111 | 112 | Network\Socket 113 | 114 | 115 | Network\Object 116 | 117 | 118 | Network\Session 119 | 120 | 121 | Network\Handler 122 | 123 | 124 | Core\Config 125 | 126 | 127 | Core 128 | 129 | 130 | Core\Config 131 | 132 | 133 | Log 134 | 135 | 136 | Log 137 | 138 | 139 | Log 140 | 141 | 142 | Log 143 | 144 | 145 | Network\Handler 146 | 147 | 148 | Network\Handler 149 | 150 | 151 | Network\Handler 152 | 153 | 154 | 155 | 156 | Core 157 | 158 | 159 | Network\Socket\Acceptor 160 | 161 | 162 | Network\Session 163 | 164 | 165 | Network\Object 166 | 167 | 168 | Memory 169 | 170 | 171 | Timer 172 | 173 | 174 | Memory\Send 175 | 176 | 177 | Memory\Send 178 | 179 | 180 | Network\NetworkIO 181 | 182 | 183 | Network\Socket 184 | 185 | 186 | Network\Session 187 | 188 | 189 | Network\Object 190 | 191 | 192 | Log 193 | 194 | 195 | Log 196 | 197 | 198 | Network\Handler 199 | 200 | 201 | Network\Handler 202 | 203 | 204 | 205 | 206 | Network\Socket\Acceptor 207 | 208 | 209 | Timer 210 | 211 | 212 | Network\Socket 213 | 214 | 215 | -------------------------------------------------------------------------------- /LBServer/LBServer.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBAcceptor.cpp: -------------------------------------------------------------------------------- 1 | #include "LBAcceptor.h" 2 | #include "LBIOContext.h" 3 | 4 | namespace LBNet 5 | { 6 | CAcceptor::CAcceptor() : __mAcceptor(CIOContext::Instance().GetIOContext()) 7 | { 8 | } 9 | 10 | CAcceptor::CAcceptor(CAcceptor&& pAcceptor) : __mAcceptor(std::move(pAcceptor.__mAcceptor)) 11 | { 12 | } 13 | 14 | CAcceptor::~CAcceptor() 15 | { 16 | Close(); 17 | } 18 | 19 | ErrCode CAcceptor::Bind(const char* pIp, unsigned short pPort) 20 | { 21 | LB_ASSERT(pIp != nullptr, "Ip Error"); 22 | 23 | boost::system::error_code aError; 24 | auto aAddress = asio::ip::make_address(pIp); 25 | asio::ip::tcp::endpoint aEndPoint(aAddress, pPort); 26 | __mAcceptor.open(aEndPoint.protocol(), aError); 27 | __mAcceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); 28 | __mAcceptor.bind(aEndPoint, aError); 29 | 30 | return aError.value(); 31 | } 32 | 33 | ErrCode CAcceptor::Bind(unsigned short pPort) 34 | { 35 | boost::system::error_code aError; 36 | asio::ip::tcp::endpoint aEndPoint(boost::asio::ip::tcp::v4(), pPort); 37 | __mAcceptor.open(aEndPoint.protocol(), aError); 38 | __mAcceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); 39 | __mAcceptor.bind(aEndPoint, aError); 40 | return aError.value(); 41 | } 42 | 43 | ErrCode CAcceptor::Listen(int pBackLog) 44 | { 45 | LB_ASSERT(__mAcceptor.is_open(), "Acceptor not Open"); 46 | 47 | boost::system::error_code aError; 48 | __mAcceptor.listen(pBackLog, aError); 49 | return aError.value(); 50 | } 51 | 52 | ErrCode CAcceptor::Accept(CSession& pSession) 53 | { 54 | LB_ASSERT(__mAcceptor.is_open(), "Acceptor not Open"); 55 | 56 | boost::system::error_code aError; 57 | __mAcceptor.accept(pSession._mSocket.GetSocket(), aError); 58 | return aError.value(); 59 | } 60 | 61 | ErrCode CAcceptor::Close() 62 | { 63 | boost::system::error_code aError; 64 | __mAcceptor.close(aError); 65 | return aError.value(); 66 | } 67 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "LBFactory.h" 2 | 3 | namespace LBNet 4 | { 5 | CFactory CFactory::__mSingleton; 6 | 7 | CFactory::CFactory() : __mPools(), __mIsInitial(false) 8 | { 9 | } 10 | 11 | CFactory::~CFactory() 12 | { 13 | } 14 | 15 | CFactory& CFactory::Instance() 16 | { 17 | return __mSingleton; 18 | } 19 | 20 | ErrCode CFactory::Initialize() 21 | { 22 | LB_ASSERT(__mIsInitial == false, "Error"); 23 | 24 | for (auto& aPair : __mPools) 25 | { 26 | aPair.second->Initialize(); 27 | } 28 | 29 | __mIsInitial = true; 30 | return 0; 31 | } 32 | 33 | ErrCode CFactory::Close() 34 | { 35 | __mPools.clear(); 36 | 37 | return 0; 38 | } 39 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBGameObject.cpp: -------------------------------------------------------------------------------- 1 | #include "LBGameObject.h" 2 | 3 | namespace LBNet 4 | { 5 | CGameObject::CGameObject() : _mSession() 6 | { 7 | } 8 | 9 | void CGameObject::LinkSession(SharedObject& pSession) 10 | { 11 | _mSession = pSession; 12 | } 13 | 14 | void CGameObject::Unlink() 15 | { 16 | _mSession = std::move(WeakObject()); 17 | } 18 | 19 | ErrCode CGameObject::Send(void* pBuffer, int pSize) 20 | { 21 | auto aShared = _mSession.lock(); 22 | if (aShared != nullptr) 23 | { 24 | return aShared->Send(pBuffer, pSize); 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | ErrCode CGameObject::Send(const SharedObject& pSender) 31 | { 32 | auto aShared = _mSession.lock(); 33 | if (aShared != nullptr) 34 | { 35 | return aShared->Send(pSender); 36 | } 37 | 38 | return 0; 39 | } 40 | 41 | void CGameObject::SetDisconnect(ErrCode pLastErr) 42 | { 43 | auto aShared = _mSession.lock(); 44 | if (aShared != nullptr) 45 | { 46 | aShared->SetDisconnect(pLastErr); 47 | } 48 | } 49 | 50 | std::string CGameObject::GetIPAddress() const 51 | { 52 | auto aShared = _mSession.lock(); 53 | if (aShared != nullptr) 54 | { 55 | return aShared->GetEndPoint().address().to_string(); 56 | } 57 | 58 | return std::string(""); 59 | } 60 | 61 | unsigned short CGameObject::GetPort() const 62 | { 63 | auto aShared = _mSession.lock(); 64 | if (aShared != nullptr) 65 | { 66 | return aShared->GetEndPoint().port(); 67 | } 68 | 69 | return 0; 70 | } 71 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBIOContext.cpp: -------------------------------------------------------------------------------- 1 | #include "LBIOContext.h" 2 | 3 | namespace LBNet 4 | { 5 | CIOContext CIOContext::__mSingleton; 6 | 7 | CIOContext::CIOContext() : __mIOContext(), __mStrand(__mIOContext), __mWork(__mIOContext) 8 | { 9 | } 10 | 11 | CIOContext::~CIOContext() 12 | { 13 | } 14 | 15 | ErrCode CIOContext::Run() 16 | { 17 | return __mIOContext.run(); 18 | } 19 | 20 | void CIOContext::Stop() 21 | { 22 | __mIOContext.stop(); 23 | } 24 | 25 | void CIOContext::Restart() 26 | { 27 | __mIOContext.restart(); 28 | } 29 | 30 | asio::io_context& CIOContext::GetIOContext() 31 | { 32 | return __mIOContext; 33 | } 34 | 35 | CIOContext& CIOContext::Instance() 36 | { 37 | return __mSingleton; 38 | } 39 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBLogProcessor.cpp: -------------------------------------------------------------------------------- 1 | #include "LBLogProcessor.h" 2 | #include "LBTimer.h" 3 | 4 | namespace LBNet 5 | { 6 | CLogProcessor CLogProcessor::__mSingleton; 7 | 8 | CLogProcessor::CLogProcessor() : __mLogSystemList(), __mLogQueue(), 9 | __mIsProcess(false) 10 | { 11 | AddLogSystem(LogOutputNo(eOutputConsole)); 12 | } 13 | 14 | CLogProcessor& CLogProcessor::Instance() 15 | { 16 | return __mSingleton; 17 | } 18 | 19 | bool CLogProcessor::PushLog(SharedObject&& pLogBuf) 20 | { 21 | LB_ASSERT(pLogBuf != nullptr, "Error!"); 22 | 23 | { 24 | WriteLock aWriteLock(*this); 25 | __mLogQueue.emplace_back(std::move(pLogBuf)); 26 | } 27 | 28 | bool aFalseValue = false; 29 | if (__mIsProcess.compare_exchange_strong(aFalseValue, true)) 30 | { 31 | CTimer::Start(1ms, [this](ErrCode pErr) 32 | { 33 | LB_ASSERT(__mIsProcess == true, "Error"); 34 | LB_ASSERT(__mProcessID == std::thread::id(), "Error"); 35 | 36 | DEBUG_CODE(__mProcessID = std::this_thread::get_id()); 37 | 38 | if(pErr == 0) 39 | ProcessLog(); 40 | 41 | DEBUG_CODE(__mProcessID = std::thread::id()); 42 | __mIsProcess.store(false); 43 | }); 44 | } 45 | 46 | return true; 47 | } 48 | 49 | ErrCode CLogProcessor::ProcessLog() 50 | { 51 | LB_ASSERT(__mIsProcess == true, "Error"); 52 | LB_ASSERT(__mProcessID == std::this_thread::get_id(), "Error"); 53 | 54 | SharedObject aBuffer = nullptr; 55 | bool aIsEmpty = true; 56 | 57 | { 58 | WriteLock aWriteLock(*this); 59 | 60 | aIsEmpty = __mLogQueue.empty(); 61 | if (aIsEmpty) 62 | { 63 | return 0; 64 | } 65 | 66 | aBuffer = __mLogQueue.front(); 67 | __mLogQueue.pop_front(); 68 | } 69 | 70 | while (!aIsEmpty) 71 | { 72 | LB_ASSERT(aBuffer != nullptr, "Error"); 73 | 74 | const auto& aLogOutIter = __mLogSystemList.find(aBuffer->GetOutput()); 75 | if (aLogOutIter != __mLogSystemList.end()) 76 | aLogOutIter->second->OnLogging(aBuffer); 77 | 78 | { 79 | WriteLock aWriteLock(*this); 80 | 81 | aIsEmpty = __mLogQueue.empty(); 82 | if (!aIsEmpty) 83 | { 84 | aBuffer = __mLogQueue.front(); 85 | __mLogQueue.pop_front(); 86 | } 87 | } 88 | } 89 | 90 | return 0; 91 | } 92 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBLogger.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Cpp/LBLogger.cpp -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBSendPool.cpp: -------------------------------------------------------------------------------- 1 | #include "LBSendPool.h" 2 | #include "LBSender.h" 3 | 4 | namespace LBNet 5 | { 6 | CSendPool::CSendPool() : __mUseFlag(), __mChunkBuffer(nullptr), 7 | __mUseSize(0), __mSenderList() 8 | { 9 | } 10 | 11 | CSendPool::~CSendPool() 12 | { 13 | SafeArrayDelete(__mChunkBuffer); 14 | } 15 | 16 | ErrCode CSendPool::Initialize(Size pChunkCnt) 17 | { 18 | LB_ASSERT(__mChunkBuffer == nullptr, "Error!"); 19 | LB_ASSERT(__mUseSize == 0, "Error!"); 20 | 21 | try 22 | { 23 | __mChunkBuffer = new CSendChunk[pChunkCnt]; 24 | } 25 | catch (...) 26 | { 27 | LB_ASSERT(0, "bad Alloc!"); 28 | return eErrCodeBadAlloc; 29 | } 30 | 31 | __mChunkCnt = pChunkCnt; 32 | 33 | for (Size index = 0; index < pChunkCnt; ++index) 34 | { 35 | __mUseFlag.emplace_back(false); 36 | __mSenderList.emplace_back(CSender()); 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | SharedObject CSendPool::Allocate(Size pSendSize) 43 | { 44 | int aIndex = 0; 45 | Size aCnt = ((pSendSize + sizeof(SendHeader)) / sizeof(CSendChunk)) + 1; 46 | CSendChunk* aSendChunk = nullptr; 47 | CSender* aSender = nullptr; 48 | 49 | { 50 | WriteLock aWriteLock(*this); 51 | aIndex = GetAllocIndex(aCnt); 52 | 53 | if (aIndex == -1) 54 | return nullptr; 55 | 56 | aSendChunk = &(__mChunkBuffer[aIndex]); 57 | aSender = &(__mSenderList[aIndex]); 58 | 59 | for (int index = aIndex; index < (aIndex + aCnt); ++index) 60 | { 61 | __mUseFlag[index] = true; 62 | } 63 | 64 | __mUseSize += (aCnt * sizeof(CSendChunk)); 65 | } 66 | 67 | aSender->SetSenderChunk(aSendChunk, aIndex, aCnt); 68 | 69 | return SharedObject(aSender, [this](CSender* pSender) 70 | { 71 | pSender->DeAllocate(); 72 | }); 73 | } 74 | 75 | bool CSendPool::DeAllocate(int pIndex, Size pCnt) 76 | { 77 | LB_ASSERT(pCnt <= __mChunkCnt, "Invalid!"); 78 | LB_ASSERT(pIndex < __mChunkCnt, "Invalid!"); 79 | 80 | { 81 | WriteLock aWriteLock(*this); 82 | 83 | for (int index = pIndex; index < (pIndex + static_cast(pCnt)); ++index) 84 | { 85 | if (__mUseFlag[index] == false) 86 | return false; 87 | 88 | __mUseFlag[index] = false; 89 | __mUseSize -= sizeof(CSendChunk); 90 | } 91 | } 92 | 93 | return true; 94 | } 95 | 96 | int CSendPool::GetAllocIndex(Size pCnt) 97 | { 98 | int aMaxCnt = 0; 99 | int aAllocIndex = -1; 100 | int aFlagIndex = 0; 101 | 102 | for (const auto& aFlag : __mUseFlag) 103 | { 104 | if (!aFlag) 105 | { 106 | ++aMaxCnt; 107 | 108 | if (aAllocIndex == -1) 109 | aAllocIndex = aFlagIndex; 110 | 111 | if (aMaxCnt == pCnt) 112 | break; 113 | } 114 | else 115 | { 116 | aMaxCnt = 0; 117 | aAllocIndex = -1; 118 | } 119 | 120 | ++aFlagIndex; 121 | } 122 | 123 | if (aAllocIndex != -1 && aMaxCnt != pCnt) 124 | aAllocIndex = -1; 125 | 126 | return aAllocIndex; 127 | } 128 | 129 | Size CSendPool::GetUsableSize() 130 | { 131 | ReadLock aLock(*this); 132 | return __mUseSize; 133 | } 134 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBSender.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Cpp/LBSender.cpp -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBServer.cpp: -------------------------------------------------------------------------------- 1 | #include "LBServer.h" 2 | 3 | namespace LBNet 4 | { 5 | constexpr Version GetLBSVersion() 6 | { 7 | return 20190729u; 8 | } 9 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBSession.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Cpp/LBSession.cpp -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBSocket.cpp: -------------------------------------------------------------------------------- 1 | #include "LBSocket.h" 2 | #include "LBIOContext.h" 3 | 4 | namespace LBNet 5 | { 6 | #pragma region CTcpSocket 7 | CTcpSocket::CTcpSocket() : _mSocket(CIOContext::Instance().GetIOContext()) 8 | { 9 | } 10 | 11 | CTcpSocket::~CTcpSocket() 12 | { 13 | Close(); 14 | } 15 | 16 | ErrCode CTcpSocket::Connect(const char* pIp, unsigned short pPort) 17 | { 18 | LB_ASSERT(pIp != nullptr, "Error"); 19 | 20 | boost::system::error_code aError; 21 | auto aAddress = asio::ip::make_address(pIp, aError); 22 | if (aError.value() != 0) 23 | return aError.value(); 24 | 25 | EndPointType aEndPoint(aAddress, pPort); 26 | _mSocket.open(aEndPoint.protocol(), aError); 27 | if (aError.value() != 0) 28 | return aError.value(); 29 | 30 | _mSocket.connect(aEndPoint, aError); 31 | return aError.value(); 32 | } 33 | 34 | ErrCode CTcpSocket::Receive(void* pBuffer, int pSize, int& pReceivedSize) 35 | { 36 | LB_ASSERT(_mSocket.is_open(), "Error"); 37 | LB_ASSERT(pBuffer != nullptr, "Error"); 38 | LB_ASSERT(pSize > 0, "Error"); 39 | 40 | boost::system::error_code aError; 41 | std::size_t aSize = _mSocket.read_some(asio::mutable_buffer(pBuffer, pSize), aError); 42 | pReceivedSize = static_cast(aSize); 43 | return aError.value(); 44 | } 45 | 46 | ErrCode CTcpSocket::Send(void* pBuffer, int pSize, int& pSendSize) 47 | { 48 | LB_ASSERT(_mSocket.is_open(), "Error"); 49 | LB_ASSERT(pBuffer != nullptr, "Error"); 50 | LB_ASSERT(pSize > 0, "Error"); 51 | 52 | boost::system::error_code aError; 53 | std::size_t aSize = _mSocket.write_some(asio::mutable_buffer(pBuffer, pSize), aError); 54 | pSendSize = static_cast(aSize); 55 | return aError.value(); 56 | } 57 | 58 | void CTcpSocket::SetReuse(bool pIsReuse) 59 | { 60 | boost::asio::socket_base::reuse_address aOption(pIsReuse); 61 | _mSocket.set_option(aOption); 62 | } 63 | 64 | ErrCode CTcpSocket::Close() 65 | { 66 | boost::system::error_code aError; 67 | 68 | if(_mSocket.is_open()) 69 | _mSocket.close(aError); 70 | 71 | return aError.value(); 72 | } 73 | 74 | const CTcpSocket::SocketType& CTcpSocket::GetSocket() const 75 | { 76 | return _mSocket; 77 | } 78 | 79 | CTcpSocket::SocketType& CTcpSocket::GetSocket() 80 | { 81 | return _mSocket; 82 | } 83 | 84 | const CTcpSocket::EndPointType CTcpSocket::GetEndPoint() const 85 | { 86 | return _mSocket.local_endpoint(); 87 | } 88 | #pragma endregion CTcpSocket 89 | 90 | #pragma region CUdpSocket 91 | CUdpSocket::CUdpSocket() : __mSocket(CIOContext::Instance().GetIOContext(), EndPointType()) 92 | { 93 | } 94 | 95 | CUdpSocket::~CUdpSocket() 96 | { 97 | Close(); 98 | } 99 | 100 | ErrCode CUdpSocket::ReceiveFrom(void* pBuffer, int pSize, int& pReceivedSize, EndPointType& pEndPoint) 101 | { 102 | LB_ASSERT(__mSocket.is_open(), "Error"); 103 | LB_ASSERT(pBuffer != nullptr, "Error"); 104 | LB_ASSERT(pSize > 0, "Error"); 105 | 106 | boost::system::error_code aError; 107 | std::size_t aSize = __mSocket.receive_from(asio::mutable_buffer(pBuffer, pSize), pEndPoint, 0, aError); 108 | pReceivedSize = static_cast(aSize); 109 | return aError.value(); 110 | } 111 | 112 | ErrCode CUdpSocket::SendTo(void* pBuffer, int pSize, int& pSendSize, EndPointType& pEndPoint) 113 | { 114 | LB_ASSERT(__mSocket.is_open(), "Error"); 115 | LB_ASSERT(pBuffer != nullptr, "Error"); 116 | LB_ASSERT(pSize > 0, "Error"); 117 | 118 | boost::system::error_code aError; 119 | std::size_t aSize = __mSocket.send_to(asio::mutable_buffer(pBuffer, pSize), pEndPoint, 0, aError); 120 | pSendSize = static_cast(aSize); 121 | return aError.value(); 122 | } 123 | 124 | void CUdpSocket::SetReuse(bool pIsReuse) 125 | { 126 | boost::asio::socket_base::reuse_address aOption(pIsReuse); 127 | __mSocket.set_option(aOption); 128 | } 129 | 130 | ErrCode CUdpSocket::Close() 131 | { 132 | boost::system::error_code aError; 133 | 134 | if (__mSocket.is_open()) 135 | __mSocket.close(aError); 136 | 137 | return aError.value(); 138 | } 139 | 140 | const CUdpSocket::SocketType& CUdpSocket::GetSocket() const 141 | { 142 | return __mSocket; 143 | } 144 | 145 | CUdpSocket::SocketType& CUdpSocket::GetSocket() 146 | { 147 | return __mSocket; 148 | } 149 | 150 | const CUdpSocket::EndPointType&& CUdpSocket::GetEndPoint() const 151 | { 152 | return __mSocket.local_endpoint(); 153 | } 154 | #pragma endregion CTcpSocket 155 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBTcpHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "LBTcpHandler.h" 2 | 3 | namespace LBNet 4 | { 5 | CTcpHandler CTcpHandler::__mSingleton; 6 | 7 | CTcpHandler& CTcpHandler::Instance() 8 | { 9 | return __mSingleton; 10 | } 11 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBTimer.cpp: -------------------------------------------------------------------------------- 1 | #include "LBTimer.h" 2 | #include "LBTime.h" 3 | #include "LBIOContext.h" 4 | 5 | namespace LBNet 6 | { 7 | CTimerTask::CTimerTask() : __mTimer(CIOContext::Instance().GetIOContext()) 8 | { 9 | } 10 | 11 | CTimerTask::CTimerTask(CTimerTask&& pTimer) : __mTimer(std::move(pTimer.__mTimer)) 12 | { 13 | } 14 | 15 | CTimerTask::CTimerTask(const CTime& pTime) : __mTimer(CIOContext::Instance().GetIOContext(), pTime.GetTimePoint()) 16 | { 17 | } 18 | 19 | CTimerTask::~CTimerTask() 20 | { 21 | } 22 | 23 | void CTimerTask::SetTime(const CTime& pTime) 24 | { 25 | __mTimer.expires_at(pTime.GetTimePoint()); 26 | } 27 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBUdpHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "LBUdpHandler.h" 2 | 3 | namespace LBNet 4 | { 5 | CUdpHandler CUdpHandler::__mSingleton; 6 | 7 | CUdpHandler& CUdpHandler::Instance() 8 | { 9 | return __mSingleton; 10 | } 11 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBUdpObject.cpp: -------------------------------------------------------------------------------- 1 | #include "LBUdpObject.h" 2 | 3 | namespace LBNet 4 | { 5 | CUdpObject::CUdpObject() : __mEndPoint() 6 | { 7 | } 8 | 9 | CUdpObject::CUdpObject(std::string&& pIp, unsigned short pPort) 10 | : __mEndPoint(boost::asio::ip::make_address(pIp), pPort) 11 | { 12 | } 13 | 14 | CUdpObject::CUdpObject(CUdpSocket::EndPointType& pEndPoint) 15 | : __mEndPoint(pEndPoint) 16 | { 17 | } 18 | 19 | CUdpObject::~CUdpObject() 20 | { 21 | } 22 | 23 | ErrCode CUdpObject::SendTo(void* pBuffer, int pSize) 24 | { 25 | return CUdpSession::Instance().SendTo(pBuffer, pSize, *this); 26 | } 27 | 28 | ErrCode CUdpObject::SendTo(SharedObject& pSender) 29 | { 30 | return CUdpSession::Instance().SendTo(pSender, *this); 31 | } 32 | 33 | std::string CUdpObject::GetIPAddress() const 34 | { 35 | return __mEndPoint.address().to_string(); 36 | } 37 | 38 | unsigned short CUdpObject::GetPort() const 39 | { 40 | return __mEndPoint.port(); 41 | } 42 | 43 | CUdpSocket::EndPointType& CUdpObject::GetEndPoint() 44 | { 45 | return __mEndPoint; 46 | } 47 | } -------------------------------------------------------------------------------- /LBServer/Src/Cpp/LBUdpSession.cpp: -------------------------------------------------------------------------------- 1 | #include "LBUdpSession.h" 2 | #include "LBUdpObject.h" 3 | #include "LBEncryption.h" 4 | 5 | namespace LBNet 6 | { 7 | CUdpSession CUdpSession::__mSingleton; 8 | 9 | CUdpSession::CUdpSession() : __mSocket(), __mBuffer(eSzPacketMax) 10 | { 11 | __mBuffer.Clear(); 12 | } 13 | 14 | CUdpSession::~CUdpSession() 15 | { 16 | } 17 | 18 | ErrCode CUdpSession::ReceiveFrom() 19 | { 20 | Size aSize = __mBuffer.GetUsableSize(); 21 | char* aWritePtr = __mBuffer.GetWritePointer(); 22 | 23 | __mSocket.ReceiveFromAsync(aWritePtr, aSize, __mEndPoint, 24 | [this](const boost::system::error_code& pError, std::size_t pRecvSize) 25 | { 26 | if (pError.value() != 0 || pRecvSize == 0) 27 | { 28 | return; 29 | } 30 | 31 | ErrCode aErr = OnReceiveFrom(static_cast(pRecvSize)); 32 | 33 | aErr = ReceiveFrom(); 34 | }); 35 | 36 | return 0; 37 | } 38 | 39 | ErrCode CUdpSession::OnReceiveFrom(Size pSize) 40 | { 41 | if (pSize == 0) 42 | return eErrCodeInvalidSize; 43 | 44 | if (!__mBuffer.OnPush(pSize)) 45 | { 46 | __mBuffer.Clear(); 47 | return eErrCodeSesBufferFull; 48 | } 49 | 50 | Size aSize = 0; 51 | ErrCode aResult = 0; 52 | char* aData = __mBuffer.Front(aSize, aResult); 53 | CUdpObject aUdpObject(__mEndPoint); 54 | 55 | LB_ASSERT(aSize >= sizeof(CPacketHeader), "Packet Error!"); 56 | 57 | while(aData != nullptr && aResult == 0) 58 | { 59 | Size aEncryptHdSize = 0; 60 | if (CEncryptor::Instance() != nullptr) 61 | { 62 | aEncryptHdSize = CEncryptor::Instance()->GetHeaderSize(); 63 | aSize -= aEncryptHdSize; 64 | aResult = CEncryptor::Instance()->Decrypt(aData, aSize); 65 | 66 | if (aResult != 0) 67 | { 68 | return aResult; 69 | } 70 | } 71 | 72 | CPacketHeader* aHeader = reinterpret_cast(aData + aEncryptHdSize); 73 | aResult = CUdpHandler::Instance().Process(aHeader->mMessage, aHeader, aSize, aUdpObject); 74 | if (aResult != 0) 75 | break; 76 | 77 | aData = __mBuffer.Front(aSize, aResult); 78 | } 79 | 80 | if (aResult != 0) 81 | return aResult; 82 | 83 | __mBuffer.Pop(); 84 | return 0; 85 | } 86 | 87 | ErrCode CUdpSession::SendTo(void* pBuffer, int pSize, CUdpObject& pObject) 88 | { 89 | __mSocket.SendToAsync(pBuffer, pSize, pObject.GetEndPoint(), 90 | [this](const boost::system::error_code& /*pError*/, std::size_t /*pSendSize*/) 91 | { 92 | }); 93 | 94 | return 0; 95 | } 96 | 97 | ErrCode CUdpSession::SendTo(SharedObject pSender, CUdpObject& pObject) 98 | { 99 | auto aSendPtr = pSender->GetSendPointer(); 100 | auto aSendSize = pSender->GetSendSize(); 101 | 102 | if (aSendPtr == nullptr) 103 | return eErrCodeNullSender; 104 | 105 | __mSocket.SendToAsync(aSendPtr, aSendSize, pObject.GetEndPoint(), 106 | [this, pSender](const boost::system::error_code& /*pError*/, std::size_t /*pSendSize*/) 107 | { 108 | }); 109 | 110 | return 0; 111 | } 112 | 113 | CUdpSession& CUdpSession::Instance() 114 | { 115 | return __mSingleton; 116 | } 117 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBAcceptor.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | void CAcceptor::AcceptAsync(CSession& pSession, THandler&& pHandler) 5 | { 6 | LB_ASSERT(__mAcceptor.is_open(), "Acceptor not Open"); 7 | 8 | __mAcceptor.async_accept(pSession._mSocket.GetSocket(), (pHandler)); 9 | } 10 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBAcceptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBAcceptor.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBBoostConfig.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBBoostConfig.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBConfig.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | inline SAddressInfo::SAddressInfo(char* pIp, unsigned int pPort) : mIp(pIp), mPort(pPort) 4 | { 5 | } 6 | 7 | inline SAddressInfo::SAddressInfo(std::string pIp, unsigned int pPort) : mIp(pIp), mPort(pPort) 8 | { 9 | } 10 | 11 | inline CConfig::CConfig() : _mThreadCnt(0), _mSessionCnt(2000), 12 | _mTimerTaskCnt(eSzTimerTask), _mLogBufCnt(eSzLogCnt) 13 | { 14 | _mThreadCnt = std::thread::hardware_concurrency() * 2; 15 | } 16 | 17 | inline void CConfig::AddAddress(char* pIP, unsigned int pPort) 18 | { 19 | _mAcceptorAddrList.emplace_back(pIP, pPort); 20 | } 21 | 22 | inline void CConfig::AddAddress(unsigned int pPort) 23 | { 24 | _mAcceptorAddrList.emplace_back("", pPort); 25 | } 26 | 27 | inline void CConfig::SetThreadCnt(unsigned pThread) 28 | { 29 | _mThreadCnt = pThread; 30 | } 31 | 32 | inline void CConfig::SetSessionCnt(unsigned pSession) 33 | { 34 | _mSessionCnt = pSession; 35 | } 36 | 37 | inline void CConfig::SetTimerTaskCnt(unsigned pTimerTask) 38 | { 39 | _mTimerTaskCnt = pTimerTask; 40 | } 41 | 42 | inline void CConfig::SetLogBufCnt(unsigned pLogBufCnt) 43 | { 44 | _mLogBufCnt = pLogBufCnt; 45 | } 46 | 47 | inline Size CConfig::GetAddressCnt() const 48 | { 49 | return static_cast(_mAcceptorAddrList.size()); 50 | } 51 | 52 | inline const SAddressInfo& CConfig::GetAddress(int pIndex) const 53 | { 54 | LB_ASSERT(pIndex < GetAddressCnt(), "Invalid!"); 55 | 56 | return _mAcceptorAddrList[pIndex]; 57 | } 58 | 59 | inline unsigned CConfig::GetThreadCnt() const 60 | { 61 | return _mThreadCnt; 62 | } 63 | 64 | inline unsigned CConfig::GetSessionCnt() const 65 | { 66 | return _mSessionCnt; 67 | } 68 | 69 | inline unsigned CConfig::GetTimerTaskCnt() const 70 | { 71 | return _mTimerTaskCnt; 72 | } 73 | 74 | inline unsigned CConfig::GetLogBufCnt() const 75 | { 76 | return _mLogBufCnt; 77 | } 78 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBConfig.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBConfig.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBError.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBError.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBFactory.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | #pragma region CObjectPoolEx 4 | template 5 | CObjectPoolEx::CObjectPoolEx(int pSize) : IObjectPool(), CObjectPool(pSize) 6 | { 7 | } 8 | 9 | template 10 | CObjectPoolEx::~CObjectPoolEx() 11 | { 12 | } 13 | 14 | template 15 | void CObjectPoolEx::Initialize() 16 | { 17 | CObjectPool::Initialize(); 18 | } 19 | 20 | template 21 | void CObjectPoolEx::Close() 22 | { 23 | CObjectPool::Close(); 24 | } 25 | #pragma endregion 26 | 27 | #pragma region CFactory 28 | template 29 | bool CFactory::AddObjectPool(int pSize) 30 | { 31 | using ObjectPool = CObjectPoolEx; 32 | std::size_t aKey = typeid(TObject).hash_code(); 33 | 34 | if (__mPools.find(aKey) != __mPools.end()) 35 | return false; 36 | 37 | __PoolPtr aPool = std::make_unique(pSize); 38 | auto aResult = __mPools.emplace(aKey, std::move(aPool)); 39 | 40 | LB_ASSERT(aResult.second == true, "Error!"); 41 | return true; 42 | } 43 | 44 | template 45 | SharedObject CFactory::New() 46 | { 47 | return New([](TObject* pObject) 48 | { 49 | if (pObject == nullptr) 50 | return false; 51 | 52 | return CFactory::Instance().Delete(pObject); 53 | }); 54 | } 55 | 56 | template 57 | SharedObject CFactory::New(TDeleter&& pDeleter) 58 | { 59 | TObject* aObject = Allocate(); 60 | return MakePtr(aObject, pDeleter); 61 | } 62 | 63 | template 64 | TObject* CFactory::Allocate() 65 | { 66 | using ObjectPool = CObjectPoolEx; 67 | 68 | std::size_t aKey = typeid(TObject).hash_code(); 69 | 70 | if (__mPools.find(aKey) == __mPools.end()) 71 | return nullptr; 72 | 73 | auto aIter = __mPools.find(aKey); 74 | __PoolPtr& aPool = aIter->second; 75 | ObjectPool* aObjPool = dynamic_cast(aPool.get()); 76 | 77 | LB_ASSERT(aObjPool != nullptr, "Exception!"); 78 | 79 | TObject* aObject = aObjPool->NewObject(); 80 | return aObject; 81 | } 82 | 83 | template 84 | bool CFactory::Delete(TObject* pObject) 85 | { 86 | using ObjectPool = CObjectPoolEx; 87 | LB_ASSERT(pObject != nullptr, "Exception!"); 88 | 89 | std::size_t aKey = typeid(TObject).hash_code(); 90 | 91 | if (__mPools.find(aKey) == __mPools.end()) 92 | return false; 93 | 94 | auto aIter = __mPools.find(aKey); 95 | __PoolPtr& aPool = aIter->second; 96 | ObjectPool* aObjPool = dynamic_cast(aPool.get()); 97 | 98 | LB_ASSERT(aObjPool != nullptr, "Exception!"); 99 | 100 | return aObjPool->DeleteObject(pObject); 101 | } 102 | 103 | template 104 | SharedObject CFactory::MakePtr(TObject*& pObject, TDeleter&& pDeleter) 105 | { 106 | return SharedObject(pObject, pDeleter); 107 | } 108 | #pragma endregion 109 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBFactory.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBFactory.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBGameObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBGameObject.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBGameServer.Inl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBGameServer.Inl -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBGameServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBGameServer.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBHandler.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | ErrCode CMessageHandler::Register(MessageNo pNumber, THandler&& pHandler) 5 | { 6 | auto aResult = __mHandlerList.emplace(pNumber, pHandler); 7 | if (aResult.second == false) 8 | return eErrCodeAlreadyRegistered; 9 | 10 | return 0; 11 | } 12 | 13 | template 14 | template 15 | ErrCode CMessageHandler::Process(MessageNo pNumber, TArgs... pArgs) 16 | { 17 | auto aIter = __mHandlerList.find(pNumber); 18 | if (aIter == __mHandlerList.end()) 19 | return eErrCodeInvalidMessage; 20 | 21 | auto aResult = aIter->second(pArgs...); 22 | return aResult; 23 | } 24 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBHandler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBHandler.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBIOContext.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | auto CIOContext::BindExecuter(THandler&& pHandler) 5 | { 6 | return asio::bind_executor(__mStrand, pHandler); 7 | } 8 | 9 | template 10 | void CIOContext::Post(THandler&& pHandler) 11 | { 12 | return __mIOContext.post(__mStrand, pHandler); 13 | } 14 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBIOContext.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBIOContext.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBLogProcessor.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | void CLogProcessor::AddLogSystem(LogOutputNo&& pOutput) 5 | { 6 | static_assert(std::is_base_of::value); 7 | 8 | if (__mLogSystemList.find(pOutput) != __mLogSystemList.end()) 9 | return; 10 | 11 | __mLogSystemList.emplace(std::move(pOutput), std::make_unique()); 12 | } 13 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBLogProcessor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBLogProcessor.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBLogger.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | #pragma region CLogBuffer 4 | template 5 | void CLogBuffer::PushLogData(TType& pData) 6 | { 7 | LB_ASSERT(__mUseSize < eSzLogMsg, "Error!"); 8 | 9 | if (__mUseSize + sizeof(TType) >= eSzLogMsg) 10 | return; 11 | 12 | TType* aDataBuffer = reinterpret_cast(__mBuffer + __mUseSize); 13 | (*aDataBuffer) = pData; 14 | __mUseSize += sizeof(TType); 15 | } 16 | 17 | template 18 | void CLogBuffer::PushLogData(TType&& pData) 19 | { 20 | LB_ASSERT(__mUseSize < eSzLogMsg, "Error!"); 21 | 22 | if (__mUseSize + sizeof(TType) >= eSzLogMsg) 23 | return; 24 | 25 | TType* aDataBuffer = reinterpret_cast(__mBuffer + __mUseSize); 26 | (*aDataBuffer) = std::move(pData); 27 | __mUseSize += sizeof(TType); 28 | } 29 | 30 | template 31 | void CLogBuffer::PushLogData(TType (&pData)[TSize]) 32 | { 33 | using NonConstDataType = std::remove_const_t; 34 | LB_ASSERT(__mUseSize < eSzLogMsg, "Error!"); 35 | 36 | if (__mUseSize + (sizeof(TType) * TSize) >= eSzLogMsg) 37 | return; 38 | 39 | NonConstDataType* aDataBuffer = reinterpret_cast(__mBuffer + __mUseSize); 40 | std::copy(pData, pData + TSize, aDataBuffer); 41 | __mUseSize += (sizeof(TType) * TSize); 42 | } 43 | 44 | template 45 | void CLogBuffer::PushLogData(TType (&&pData)[TSize]) 46 | { 47 | using NonConstDataType = std::remove_const_t; 48 | LB_ASSERT(__mUseSize < eSzLogMsg, "Error!"); 49 | 50 | if (__mUseSize + (sizeof(TType) * TSize) >= eSzLogMsg) 51 | return; 52 | 53 | NonConstDataType* aDataBuffer = reinterpret_cast(__mBuffer + __mUseSize); 54 | std::move(pData, pData + TSize, aDataBuffer); 55 | __mUseSize += (sizeof(TType) * TSize); 56 | } 57 | 58 | template <> 59 | void CLogBuffer::PushLogData(const char*& pData) 60 | { 61 | LB_ASSERT(__mUseSize < eSzLogMsg, "Error!"); 62 | 63 | Size aLength = static_cast(StrLen(pData, eSzLogMsg - __mUseSize)); 64 | if (__mUseSize + aLength >= eSzLogMsg) 65 | return; 66 | 67 | char* aDataBuffer = reinterpret_cast(__mBuffer + __mUseSize); 68 | std::copy(pData, pData + aLength, aDataBuffer); 69 | __mUseSize += aLength; 70 | } 71 | 72 | template <> 73 | void CLogBuffer::PushLogData(const char*&& pData) 74 | { 75 | LB_ASSERT(__mUseSize < eSzLogMsg, "Error!"); 76 | 77 | Size aLength = static_cast(StrLen(pData, eSzLogMsg - __mUseSize)); 78 | if (__mUseSize + aLength >= eSzLogMsg) 79 | return; 80 | 81 | char* aDataBuffer = reinterpret_cast(__mBuffer + __mUseSize); 82 | std::move(pData, pData + aLength, aDataBuffer); 83 | __mUseSize += aLength; 84 | } 85 | #pragma endregion CLogBuffer 86 | 87 | #pragma region CLogger 88 | template 89 | CLogger& CLogger::operator<<(TArgs&& pData) 90 | { 91 | if (_mLogBuffer != nullptr) 92 | _mLogBuffer->PushLogData(std::forward(pData)); 93 | 94 | return (*this); 95 | } 96 | #pragma endregion CLogger 97 | 98 | #pragma region CConsoleLog 99 | template 100 | CConsoleLog& CConsoleLog::operator<<(TArgs&& pData) 101 | { 102 | return (__PushLogImpl(pData, TIsScalar())); 103 | } 104 | 105 | template 106 | CConsoleLog& CConsoleLog::__PushLogImpl(TArgs&& pData, std::true_type) 107 | { 108 | if(_mLogBuffer == nullptr) 109 | return (*this); 110 | 111 | std::string aScalarToStr(std::to_string(pData)); 112 | __mLogString += aScalarToStr.c_str(); 113 | _mLogBuffer->OnPushed(static_cast(aScalarToStr.length())); 114 | 115 | return (*this); 116 | } 117 | 118 | template 119 | CConsoleLog& CConsoleLog::__PushLogImpl(TArgs&& pData, std::false_type) 120 | { 121 | if (_mLogBuffer == nullptr) 122 | return (*this); 123 | 124 | __mLogString += std::forward(pData); 125 | _mLogBuffer->OnPushed(StrLen(pData, eSzLogMsg - _mLogBuffer->GetUseSize())); 126 | 127 | return (*this); 128 | } 129 | #pragma endregion CConsoleLog 130 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBLogger.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBLogger.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBPacketHeader.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBPacketHeader.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBSendPool.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBSendPool.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBSender.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | SharedObject CSender::Allocate() 5 | { 6 | return CSender::Allocate(sizeof(TObject)); 7 | } 8 | 9 | template 10 | TObject* CSender::GetWritePointer() 11 | { 12 | auto aPtr = reinterpret_cast(__mChunk); 13 | return reinterpret_cast(aPtr + sizeof(SendHeader) + GetEncryptHdSize()); 14 | } 15 | 16 | template 17 | void CSender::SetData(TObject& pObject) 18 | { 19 | LB_ASSERT(sizeof(TObject) <= __mChunkCount * eSzSendChunk - GetEncryptHdSize(), "Error"); 20 | auto aPtr = reinterpret_cast(__mChunk); 21 | auto aDataPtr = reinterpret_cast(aPtr + sizeof(SendHeader) + GetEncryptHdSize()); 22 | 23 | (*aDataPtr) = pObject; 24 | } 25 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBSender.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBSender.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBServer.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBSession.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | void CSession::SetGameObject(SharedObject& pObject) 5 | { 6 | static_assert(std::is_base_of::value == true); 7 | 8 | LB_ASSERT(__mGameObject.get() == nullptr, "Error!"); 9 | LB_ASSERT(pObject.get() != nullptr, "Error!"); 10 | 11 | __mGameObject = std::static_pointer_cast(pObject); 12 | } 13 | 14 | template 15 | SharedObject CSession::GetGameObject() 16 | { 17 | static_assert(std::is_base_of::value == true); 18 | 19 | return __GetGameObjectImpl(std::is_same()); 20 | } 21 | 22 | template 23 | SharedObject CSession::__GetGameObjectImpl(std::true_type) 24 | { 25 | return __mGameObject; 26 | } 27 | 28 | template 29 | SharedObject CSession::__GetGameObjectImpl(std::false_type) 30 | { 31 | return SharedCast(__mGameObject); 32 | } 33 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBSession.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBSession.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBShard.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | inline CShard::CShard() : CSession(), __mServerNo(0), 5 | __mIp(), __mPort(0), __mNextConnect(true) 6 | { 7 | static_assert(std::is_base_of::value == true); 8 | } 9 | 10 | template 11 | ErrCode CShard::Initialize() 12 | { 13 | __super::Initialize(); 14 | 15 | return Connect(); 16 | } 17 | 18 | template 19 | ErrCode CShard::Connect() 20 | { 21 | _mSocket.ConnectAsync(__mIp.c_str(), __mPort, 22 | [this](const boost::system::error_code& pError) 23 | { 24 | auto aShardObject = GetGameObject(); 25 | if (pError.value() != 0) 26 | { 27 | __OnConnectFail(pError.value()); 28 | return; 29 | } 30 | 31 | ErrCode aErr = OnAccept(); 32 | if (aErr != 0) 33 | { 34 | __OnConnectFail(aErr); 35 | } 36 | 37 | _mLastError = 0; 38 | aErr = aShardObject->OnConnect(); 39 | if (aErr != 0) 40 | { 41 | __OnConnectFail(aErr); 42 | return; 43 | } 44 | }); 45 | 46 | return 0; 47 | } 48 | 49 | template 50 | ErrCode CShard::SetDisconnect(ErrCode pError) 51 | { 52 | LB_ASSERT(_mLastError == 0, "Invalid!"); 53 | 54 | WriteLock aLock(*this); 55 | 56 | if (_mState != EState::eDisconnect) 57 | { 58 | _mSocket.Close(); 59 | _mState = EState::eDisconnect; 60 | _mLastError = pError; 61 | 62 | LB_ASSERT(GetGameObject() != nullptr, "Error!"); 63 | GetGameObject()->OnDisconnect(); 64 | } 65 | 66 | return 0; 67 | } 68 | 69 | template 70 | void CShard::__OnConnectFail(ErrCode pErr) 71 | { 72 | auto aShardObject = GetGameObject(); 73 | 74 | WriteLock aLock(*this); 75 | 76 | __mNextConnect = aShardObject->OnConnectFail(pErr); 77 | 78 | if (__mNextConnect) 79 | Connect(); 80 | else 81 | SetDisconnect(); 82 | } 83 | 84 | template 85 | inline void CShard::SetAddress(const char* pIp, unsigned short pPort) 86 | { 87 | LB_ASSERT(pIp != nullptr, "Error!"); 88 | 89 | __mIp = pIp; 90 | __mPort = pPort; 91 | } 92 | 93 | template 94 | inline void CShard::SetServerNo(unsigned short pServerNo) 95 | { 96 | __mServerNo = pServerNo; 97 | } 98 | 99 | template 100 | inline unsigned short CShard::GetServerNo() const 101 | { 102 | return __mServerNo; 103 | } 104 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBShard.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBShard.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBShardObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBShardObject.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBSocket.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | #pragma region CTcpSocket 4 | template 5 | ErrCode CTcpSocket::ConnectAsync(const char* pIp, unsigned short pPort, THandler&& pHandler) 6 | { 7 | LB_ASSERT(pIp != nullptr, "Error"); 8 | 9 | boost::system::error_code aError; 10 | auto aAddress = asio::ip::make_address(pIp, aError); 11 | if (aError.value() != 0) 12 | return aError.value(); 13 | 14 | EndPointType aEndPoint(aAddress, pPort); 15 | _mSocket.open(aEndPoint.protocol(), aError); 16 | if (aError.value() != 0) 17 | return aError.value(); 18 | 19 | _mSocket.async_connect(aEndPoint, CIOContext::Instance().BindExecuter(pHandler)); 20 | return 0; 21 | } 22 | 23 | template 24 | void CTcpSocket::ReceiveAsync(void* pBuffer, int pSize, THandler&& pHandler) 25 | { 26 | LB_ASSERT(_mSocket.is_open(), "Error"); 27 | LB_ASSERT(pBuffer != nullptr, "Error"); 28 | LB_ASSERT(pSize > 0, "Error"); 29 | 30 | _mSocket.async_read_some(asio::mutable_buffer(pBuffer, pSize), CIOContext::Instance().BindExecuter(pHandler)); 31 | } 32 | 33 | template 34 | void CTcpSocket::SendAsync(void* pBuffer, int pSize, THandler&& pHandler) 35 | { 36 | LB_ASSERT(_mSocket.is_open(), "Error"); 37 | LB_ASSERT(pBuffer != nullptr, "Error"); 38 | LB_ASSERT(pSize > 0, "Error"); 39 | 40 | _mSocket.async_write_some(asio::mutable_buffer(pBuffer, pSize), CIOContext::Instance().BindExecuter(pHandler)); 41 | } 42 | #pragma endregion CTcpSocket 43 | 44 | #pragma region CUdpSocket 45 | template 46 | void CUdpSocket::ReceiveFromAsync(void* pBuffer, int pSize, EndPointType& pEndPoint, THandler&& pHandler) 47 | { 48 | LB_ASSERT(__mSocket.is_open(), "Error"); 49 | LB_ASSERT(pBuffer != nullptr, "Error"); 50 | LB_ASSERT(pSize > 0, "Error"); 51 | 52 | __mSocket.async_receive_from(asio::mutable_buffer(pBuffer, pSize), pEndPoint, CIOContext::Instance().BindExecuter(pHandler)); 53 | } 54 | 55 | template 56 | void CUdpSocket::SendToAsync(void* pBuffer, int pSize, EndPointType& pEndPoint, THandler&& pHandler) 57 | { 58 | LB_ASSERT(__mSocket.is_open(), "Error"); 59 | LB_ASSERT(pBuffer != nullptr, "Error"); 60 | LB_ASSERT(pSize > 0, "Error"); 61 | 62 | __mSocket.async_send_to(asio::mutable_buffer(pBuffer, pSize), pEndPoint, CIOContext::Instance().BindExecuter(pHandler)); 63 | } 64 | #pragma endregion CUdpSocket 65 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBSocket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBSocket.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBTcpHandler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBTcpHandler.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBTimer.Inl: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace LBNet 4 | { 5 | #pragma region CTimerTask 6 | template 7 | CTimerTask::CTimerTask(const std::chrono::duration& pTime) 8 | : __mTimer(CIOContext::Instance().GetIOContext(), pTime) 9 | { 10 | } 11 | 12 | template 13 | void CTimerTask::SetTime(const std::chrono::duration& pTime) 14 | { 15 | __mTimer.expires_after(pTime); 16 | } 17 | 18 | template 19 | void CTimerTask::Start(THandler&& pHandler, TArgs... pArgs) 20 | { 21 | __mTimer.async_wait([pHandler, pArgs...](const boost::system::error_code& pErr) 22 | { 23 | ErrCode aErr = pErr.value(); 24 | pHandler(aErr, pArgs...); 25 | }); 26 | } 27 | #pragma endregion CTimerTask 28 | 29 | #pragma region CTimer 30 | template 31 | ErrCode CTimer::Start(const std::chrono::duration&& pTime, 32 | THandler&& pHandler, TArgs... pArgs) 33 | { 34 | auto aTask = CFactory::Instance().New(); 35 | if (aTask == nullptr) 36 | return eErrCodeNotEnoughRsc; 37 | 38 | aTask->SetTime(pTime); 39 | aTask->Start([aTask, pHandler, pArgs...](ErrCode pErr) 40 | { 41 | pHandler(pErr, pArgs...); 42 | }); 43 | 44 | return 0; 45 | } 46 | template 47 | ErrCode CTimer::Start(const std::chrono::duration& pTime, 48 | THandler&& pHandler, TArgs... pArgs) 49 | { 50 | auto aTask = CFactory::Instance().New(); 51 | if (aTask == nullptr) 52 | return eErrCodeNotEnoughRsc; 53 | 54 | aTask->SetTime(pTime); 55 | aTask->Start([aTask, pHandler, pArgs...](ErrCode pErr) 56 | { 57 | pHandler(pErr, pArgs...); 58 | }); 59 | 60 | return 0; 61 | } 62 | 63 | template 64 | ErrCode CTimer::Start(const CTime& pTime, THandler&& pHandler, TArgs... pArgs) 65 | { 66 | auto aTask = CFactory::Instance().New(); 67 | if (aTask == nullptr) 68 | return eErrCodeNotEnoughRsc; 69 | 70 | aTask->SetTime(pTime); 71 | aTask->Start([aTask, pHandler, pArgs...](ErrCode pErr) 72 | { 73 | pHandler(pErr, pArgs...); 74 | }); 75 | 76 | return 0; 77 | } 78 | 79 | template 80 | ErrCode CTimer::Start(CTimerTask& pTimer, THandler&& pHandler, TArgs... pArgs) 81 | { 82 | pTimer.Start([pHandler, pArgs...](ErrCode pErr) 83 | { 84 | pHandler(pErr, pArgs...); 85 | }); 86 | 87 | return 0; 88 | } 89 | #pragma endregion CTimer 90 | } -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBTimer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBTimer.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBUdpHandler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBUdpHandler.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBUdpObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBUdpObject.h -------------------------------------------------------------------------------- /LBServer/Src/Inc/LBUdpSession.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/LBServer/Src/Inc/LBUdpSession.h -------------------------------------------------------------------------------- /LBUtility/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2) 2 | 3 | project(LBUtility) 4 | set(TARGET LBUtility) 5 | 6 | set(CMAKE_CONFIGURATION_TYPES "Debug;Release" 7 | CACHE STRING "Configuration types" FORCE) 8 | 9 | set(LBENGINE_OUT_DIRECTORY "/bin") 10 | 11 | INCLUDE_DIRECTORIES(Src/Inc) 12 | 13 | # Compile options 14 | include(../Build/CMake/CompileOptions.cmake) 15 | 16 | # Source 17 | file(GLOB_RECURSE HEADERS 18 | ${CMAKE_CURRENT_SOURCE_DIR}/Src/Inc/*.h) 19 | 20 | file(GLOB_RECURSE SOURCES 21 | ${CMAKE_CURRENT_SOURCE_DIR}/Src/Cpp/*.cpp) 22 | 23 | add_library(LBUtility SHARED 24 | ${SOURCES} 25 | ) 26 | 27 | # Set postfix by configuration 28 | if(CMAKE_CONFIGURATION_TYPES STREQUAL "Debug") 29 | set(CONFIGURATUON_POSTFIX "D") 30 | else(CMAKE_CONFIGURATION_TYPES STREQUAL "Release") 31 | set(CONFIGURATUON_POSTFIX "") 32 | endif() 33 | 34 | set(OUTPUT_FILE_NAME "LBUtility${CONFIGURATUON_POSTFIX}_x64") 35 | 36 | # Output file name 37 | set_target_properties(LBUtility 38 | PROPERTIES 39 | OUTPUT_NAME_DEBUG ${OUTPUT_FILE_NAME} 40 | OUTPUT_NAME_RELEASE ${OUTPUT_FILE_NAME} 41 | ) 42 | 43 | # Preprocessor definitions 44 | target_compile_definitions(LBUtility PRIVATE 45 | $<$:_UNICODE;X64;_DEBUG;_CONSOLE> 46 | $<$:_UNICODE;X64;NDEBUG;_CONSOLE> 47 | ) 48 | 49 | # SDL check 50 | if (MSVC) 51 | target_compile_options(LBUtility PRIVATE 52 | "$<$:/sdl>" 53 | "$<$:/sdl>" 54 | ) 55 | endif() 56 | 57 | # Minimal rebuild 58 | if (MSVC) 59 | target_compile_options(LBUtility PRIVATE 60 | "$<$:/Gm->" 61 | "$<$:/Gm->" 62 | ) 63 | endif () -------------------------------------------------------------------------------- /LBUtility/LBUtility.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | false 39 | false 40 | false 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 15.0 63 | {30E01DDD-EAAB-48ED-9171-E451C1A2EE3A} 64 | Win32Proj 65 | LBUtility 66 | 10.0.17763.0 67 | 68 | 69 | 70 | DynamicLibrary 71 | true 72 | v141 73 | Unicode 74 | 75 | 76 | DynamicLibrary 77 | false 78 | v141 79 | true 80 | Unicode 81 | 82 | 83 | DynamicLibrary 84 | true 85 | v141 86 | Unicode 87 | 88 | 89 | DynamicLibrary 90 | false 91 | v141 92 | true 93 | Unicode 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | true 116 | $(ProjectName)D_$(PlatformTarget) 117 | $(ProjectDir)Src\Inc;$(VC_IncludePath);$(WindowsSDK_IncludePath) 118 | $(ReferencePath) 119 | $(SolutionDir)Bin\ 120 | $(SolutionDir)Intermediate\$(ProjectName)\ 121 | 122 | 123 | true 124 | $(ProjectName)D_$(PlatformTarget) 125 | $(ProjectDir)Src\Inc;$(IncludePath) 126 | $(ReferencePath) 127 | $(SolutionDir)Bin\ 128 | $(SolutionDir)Intermediate\$(ProjectName)\ 129 | 130 | 131 | false 132 | $(ProjectDir)Src\Inc;$(VC_IncludePath);$(WindowsSDK_IncludePath) 133 | $(ReferencePath) 134 | $(ProjectName)_$(PlatformTarget) 135 | $(SolutionDir)Bin\ 136 | $(SolutionDir)Intermediate\$(ProjectName)\ 137 | 138 | 139 | false 140 | $(ProjectDir)Src\Inc;$(VC_IncludePath);$(WindowsSDK_IncludePath) 141 | $(ReferencePath) 142 | $(ProjectName)_$(PlatformTarget) 143 | $(SolutionDir)Bin\ 144 | $(SolutionDir)Intermediate\$(ProjectName)\ 145 | 146 | 147 | 148 | NotUsing 149 | Level4 150 | Disabled 151 | true 152 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 153 | true 154 | true 155 | stdcpp17 156 | %(AdditionalIncludeDirectories) 157 | Disabled 158 | 159 | 160 | Console 161 | true 162 | 163 | 164 | 165 | 166 | NotUsing 167 | Level4 168 | Disabled 169 | true 170 | X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 171 | true 172 | stdcpp17 173 | %(AdditionalIncludeDirectories) 174 | Disabled 175 | 176 | 177 | Console 178 | true 179 | 180 | 181 | 182 | 183 | NotUsing 184 | Level4 185 | MaxSpeed 186 | true 187 | true 188 | true 189 | X86;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 190 | true 191 | stdcpp17 192 | %(AdditionalIncludeDirectories) 193 | 194 | 195 | Console 196 | true 197 | true 198 | true 199 | 200 | 201 | 202 | 203 | NotUsing 204 | Level4 205 | MaxSpeed 206 | true 207 | true 208 | true 209 | X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 210 | true 211 | stdcpp17 212 | %(AdditionalIncludeDirectories) 213 | 214 | 215 | Console 216 | true 217 | true 218 | true 219 | 220 | 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /LBUtility/LBUtility.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Time 6 | 7 | 8 | Locker 9 | 10 | 11 | Core 12 | 13 | 14 | Memory 15 | 16 | 17 | Encryption 18 | 19 | 20 | 21 | 22 | {426df0d8-42bd-49a5-b11d-c0d228cd392c} 23 | 24 | 25 | {a3013509-da28-4471-9fc8-c3826a5e0eda} 26 | 27 | 28 | {f58efba7-f9c9-43c2-acc7-9cdb5669d7ae} 29 | 30 | 31 | {bb200860-9dae-45a6-b79b-631575835f8f} 32 | 33 | 34 | {d41a3ab6-b6d8-4fa0-b1e7-bf505284da50} 35 | 36 | 37 | {93faa777-6c30-460c-9437-60e397862136} 38 | 39 | 40 | {6cc994ac-d803-4f81-9f5a-6f347635d36e} 41 | 42 | 43 | {205f3e3d-627f-4f09-b96b-4ac0471da3ed} 44 | 45 | 46 | {e8a31dc3-052a-4494-bd28-e94f91bd64e7} 47 | 48 | 49 | {7ae75800-1014-40c3-8ec2-0518d3313c94} 50 | 51 | 52 | 53 | 54 | CharSet\String 55 | 56 | 57 | CharSet 58 | 59 | 60 | Time 61 | 62 | 63 | Locker 64 | 65 | 66 | Memory 67 | 68 | 69 | Core 70 | 71 | 72 | File 73 | 74 | 75 | Random 76 | 77 | 78 | Random 79 | 80 | 81 | Encryption 82 | 83 | 84 | Memory\Container 85 | 86 | 87 | Memory\Container 88 | 89 | 90 | 91 | 92 | CharSet\String 93 | 94 | 95 | File 96 | 97 | 98 | Random 99 | 100 | 101 | Random 102 | 103 | 104 | Time 105 | 106 | 107 | Memory\Container 108 | 109 | 110 | Memory\Container 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /LBUtility/LBUtility.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WindowsLocalDebugger 5 | 6 | -------------------------------------------------------------------------------- /LBUtility/Src/Cpp/LBBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "LBBuffer.h" 2 | 3 | namespace LBNet 4 | { 5 | /** 6 | @brief CBuffer�� ������ 7 | */ 8 | CBuffer::CBuffer(Size pSize) : _mMAX_SIZE(pSize), _mUseSize(0), 9 | _mReadIndex(0), _mWriteIndex(0), _mBuffer(nullptr) 10 | { 11 | _mBuffer = new char[_mMAX_SIZE]; 12 | ::memset(_mBuffer, 0, _mMAX_SIZE); 13 | } 14 | 15 | CBuffer::~CBuffer() 16 | { 17 | delete[] _mBuffer; 18 | } 19 | 20 | bool CBuffer::Push(const char* pData, Size pSize) 21 | { 22 | LB_ASSERT(pData != nullptr, "Error!"); 23 | LB_ASSERT(pSize > 0, "Error!"); 24 | 25 | Size aDataSize = static_cast(sizeof(CBufferHeader)) + pSize; 26 | if (aDataSize > GetUsableSize()) 27 | return false; 28 | 29 | reinterpret_cast(_mBuffer + _mWriteIndex)->mDataSize = pSize; 30 | ::memcpy_s(_mBuffer + _mWriteIndex + sizeof(CBufferHeader), GetUsableSize() - sizeof(CBufferHeader), pData, pSize); 31 | _mUseSize += pSize + sizeof(CBufferHeader); 32 | _mWriteIndex += static_cast(pSize) + sizeof(CBufferHeader); 33 | return true; 34 | } 35 | 36 | char* CBuffer::Front(Size& pSize, ErrCode& pErr) 37 | { 38 | if (static_cast(_mUseSize) - _mReadIndex < static_cast(sizeof(CBufferHeader))) 39 | return nullptr; 40 | 41 | pErr = 0; 42 | char* aData = _mBuffer + _mReadIndex; 43 | pSize = reinterpret_cast(aData)->mDataSize; 44 | aData += sizeof(CBufferHeader); 45 | 46 | // �߸��� ��Ŷ�� ���� ��� ����� ���������� ���´�. 47 | // �̷��� ��� ������ �����Ѵ�. 48 | if (pSize > _mMAX_SIZE - sizeof(CBufferHeader)) 49 | { 50 | pErr = 1; 51 | return nullptr; 52 | } 53 | 54 | if (pSize > _mUseSize - static_cast(_mReadIndex) - sizeof(CBufferHeader)) 55 | return nullptr; 56 | 57 | _mReadIndex += (static_cast(pSize) + static_cast(sizeof(CBufferHeader))); 58 | return aData; 59 | } 60 | 61 | void CBuffer::Pop() 62 | { 63 | LB_ASSERT(_mUseSize >= static_cast(_mReadIndex), "Error!"); 64 | 65 | ::memmove_s(_mBuffer, _mMAX_SIZE, _mBuffer + _mReadIndex, _mMAX_SIZE - _mReadIndex); 66 | _mWriteIndex -= _mReadIndex; 67 | _mUseSize -= static_cast(_mReadIndex); 68 | _mReadIndex = 0; 69 | } 70 | 71 | void CBuffer::Clear() 72 | { 73 | _mReadIndex = 0; 74 | _mUseSize = 0; 75 | _mWriteIndex = 0; 76 | } 77 | 78 | bool CBuffer::OnPush(Size pSize) 79 | { 80 | LB_ASSERT(GetUsableSize() >= pSize, "Invalid Size!"); 81 | LB_ASSERT(_mReadIndex == 0, "Invalid Idx!"); 82 | 83 | if (_mWriteIndex + pSize > _mMAX_SIZE) 84 | return false; 85 | 86 | _mWriteIndex += static_cast(pSize); 87 | _mUseSize += pSize; 88 | 89 | return true; 90 | } 91 | 92 | char* CBuffer::GetWritePointer() 93 | { 94 | LB_ASSERT(_mWriteIndex < _mMAX_SIZE, "Invalid Address!"); 95 | return &(_mBuffer[_mWriteIndex]); 96 | } 97 | 98 | Size CBuffer::GetUsingSize() const 99 | { 100 | return _mUseSize; 101 | } 102 | 103 | Size CBuffer::GetUsableSize() const 104 | { 105 | return _mMAX_SIZE - _mUseSize; 106 | } 107 | 108 | Size CBuffer::GetBufferSize() 109 | { 110 | return _mMAX_SIZE; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /LBUtility/Src/Cpp/LBEncryption.cpp: -------------------------------------------------------------------------------- 1 | #include "LBEncryption.h" 2 | 3 | namespace LBNet 4 | { 5 | CEncryptor* CEncryptor::__mSingleton = nullptr; 6 | 7 | CEncryptor::CEncryptor() : _mHeaderSize(0) 8 | { 9 | LB_ASSERT(__mSingleton == nullptr, "Invalid!"); 10 | __mSingleton = this; 11 | } 12 | 13 | CEncryptor::~CEncryptor() 14 | { 15 | } 16 | 17 | Size CEncryptor::GetHeaderSize() 18 | { 19 | LB_ASSERT(_mHeaderSize > 0, "Invalid Header Size!"); 20 | return _mHeaderSize; 21 | } 22 | 23 | CEncryptor* CEncryptor::Instance() 24 | { 25 | return __mSingleton; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LBUtility/Src/Cpp/LBLocker.cpp: -------------------------------------------------------------------------------- 1 | #include "LBLocker.h" 2 | 3 | namespace LBNet 4 | { 5 | #ifdef _DEBUG 6 | CSharedMutex::CSharedMutex() : __mMutex() 7 | { 8 | } 9 | 10 | void CSharedMutex::lock() 11 | { 12 | __mMutex.lock(); 13 | DEBUG_CODE(__mOwner = std::this_thread::get_id()); 14 | } 15 | 16 | void CSharedMutex::unlock() 17 | { 18 | __mMutex.unlock(); 19 | DEBUG_CODE(__mOwner = std::thread::id()); 20 | } 21 | 22 | bool CSharedMutex::try_lock() 23 | { 24 | auto aResult = __mMutex.try_lock(); 25 | 26 | if (aResult) 27 | { 28 | __mOwner = std::this_thread::get_id(); 29 | } 30 | 31 | return aResult; 32 | } 33 | 34 | void CSharedMutex::lock_shared() 35 | { 36 | __mMutex.lock_shared(); 37 | DEBUG_CODE(__mOwner = std::this_thread::get_id()); 38 | } 39 | 40 | void CSharedMutex::unlock_shared() 41 | { 42 | __mMutex.unlock_shared(); 43 | DEBUG_CODE(__mOwner = std::thread::id()); 44 | } 45 | 46 | bool CSharedMutex::try_lock_shared() 47 | { 48 | auto aResult = __mMutex.try_lock_shared(); 49 | 50 | if (aResult) 51 | { 52 | __mOwner = std::this_thread::get_id(); 53 | } 54 | 55 | return aResult; 56 | } 57 | #endif //_DEBUG 58 | } 59 | -------------------------------------------------------------------------------- /LBUtility/Src/Cpp/LBTime.cpp: -------------------------------------------------------------------------------- 1 | #include "LBTime.h" 2 | 3 | namespace LBNet 4 | { 5 | const CTime CTime::__mStartTime; 6 | 7 | /** 8 | @brief CTime�� ������ 9 | @details �ð��� ���� �ð����� �����Ѵ�. 10 | */ 11 | CTime::CTime() : __mTimePoint(), __mLocalTime() 12 | { 13 | SetNow(); 14 | } 15 | 16 | /** 17 | @brief CTime�� +=������ 18 | */ 19 | CTime& CTime::operator+=(const CTime& pTime) 20 | { 21 | __mTimePoint += pTime.GetTimePoint().time_since_epoch(); 22 | __UpdateFromTimePoint(); 23 | 24 | return (*this); 25 | } 26 | 27 | /** 28 | @brief CTime�� -=������ 29 | */ 30 | CTime& CTime::operator-=(const CTime& pTime) 31 | { 32 | __mTimePoint -= pTime.GetTimePoint().time_since_epoch(); 33 | __UpdateFromTimePoint(); 34 | 35 | return (*this); 36 | } 37 | 38 | /** 39 | @brief CTime�� +������ 40 | */ 41 | CTime CTime::operator+(const CTime& pTime) 42 | { 43 | CTime aTime; 44 | TimePoint point = __mTimePoint + pTime.GetTimePoint().time_since_epoch(); 45 | aTime.SetTimePoint(std::move(point)); 46 | 47 | return aTime; 48 | } 49 | 50 | /** 51 | @brief CTime�� -������ 52 | */ 53 | CTime CTime::operator-(const CTime& pTime) 54 | { 55 | CTime time; 56 | TimePoint point = __mTimePoint - pTime.GetTimePoint().time_since_epoch(); 57 | time.SetTimePoint(std::move(point)); 58 | 59 | return time; 60 | } 61 | 62 | /** 63 | @brief �ð��� ���� �ð����� �����ϴ� �Լ� 64 | */ 65 | void CTime::SetNow() 66 | { 67 | using namespace std::chrono; 68 | __mTimePoint = system_clock::now(); 69 | time_t time = std::move(system_clock::to_time_t(__mTimePoint)); 70 | 71 | ::LOCALTIME(&__mLocalTime, &time); 72 | __mLocalTime.tm_year += 1900; 73 | } 74 | 75 | /** 76 | @brief ������ �����ϴ� �Լ� 77 | @param int pYear ������ ���� 78 | */ 79 | void CTime::SetYear(int pYear) 80 | { 81 | __mLocalTime.tm_year = pYear; 82 | __UpdateFromLocalTime(); 83 | } 84 | 85 | /** 86 | @brief ���� �����ϴ� �Լ� 87 | @param int pMonth ������ �� 88 | */ 89 | void CTime::SetMonth(int pMonth) 90 | { 91 | LB_ASSERT(pMonth >= 0 && pMonth < 12, "Invalid Value!"); 92 | 93 | __mLocalTime.tm_mon = pMonth; 94 | __UpdateFromLocalTime(); 95 | } 96 | 97 | /** 98 | @brief ���� �����ϴ� �Լ� 99 | @param int pDay ������ �� 100 | */ 101 | void CTime::SetDay(int pDay) 102 | { 103 | LB_ASSERT(pDay >= 0 && pDay <= 31, "Invalid Value!"); 104 | 105 | __mLocalTime.tm_mday = pDay; 106 | __UpdateFromLocalTime(); 107 | } 108 | 109 | /** 110 | @brief �ð��� �����ϴ� �Լ� 111 | @param int pHour ������ �ð� 112 | */ 113 | void CTime::SetHour(int pHour) 114 | { 115 | LB_ASSERT(pHour >= 0 && pHour <= 24, "Invalid Value!"); 116 | 117 | __mLocalTime.tm_hour = pHour; 118 | __UpdateFromLocalTime(); 119 | } 120 | 121 | /** 122 | @brief ���� �����ϴ� �Լ� 123 | @param int pMoinute ������ �� 124 | */ 125 | void CTime::SetMinute(int pMinute) 126 | { 127 | LB_ASSERT(pMinute >= 0 && pMinute <= 60, "Invalid Value!"); 128 | 129 | __mLocalTime.tm_min = pMinute; 130 | __UpdateFromLocalTime(); 131 | } 132 | 133 | /** 134 | @brief �ʸ� �����ϴ� �Լ� 135 | @param int pSecond ������ �� 136 | */ 137 | void CTime::SetSecond(int pSecond) 138 | { 139 | LB_ASSERT(pSecond >= 0 && pSecond <= 60, "Invalid Value!"); 140 | 141 | __mLocalTime.tm_sec = pSecond; 142 | __UpdateFromLocalTime(); 143 | } 144 | 145 | /** 146 | @brief TimePoint�� �����ϴ� �Լ� 147 | @param TimePoint pTimePoint ������ TimePoint 148 | */ 149 | void CTime::SetTimePoint(TimePoint pTimePoint) 150 | { 151 | __mTimePoint = pTimePoint; 152 | __UpdateFromTimePoint(); 153 | } 154 | 155 | /** 156 | @brief TimePoint�� ��ȯ�ϴ� �Լ� 157 | */ 158 | CTime::TimePoint CTime::GetTimePoint() const 159 | { 160 | return __mTimePoint; 161 | } 162 | 163 | /** 164 | @brief ������ �ð� ƽ�� ���ϴ� �Լ� 165 | @details ������ ƽ�� �ð��� ms������ ��ȯ�Ѵ�. 166 | @return Tick ������ �ð� ƽduration(ms) 167 | */ 168 | Tick CTime::ToTick() const 169 | { 170 | return std::chrono::duration_cast(__mTimePoint.time_since_epoch()); 171 | } 172 | 173 | /** 174 | @brief ������ �ð� ƽ�� ���ϴ� �Լ� 175 | @details ������ ƽ�� ����� �ð��� ms������ ��ȯ�Ѵ�. 176 | @return Tick ������ �ð� ƽTickCount(ms) 177 | */ 178 | TickCount CTime::ToTickCount() const 179 | { 180 | return std::chrono::duration_cast(__mTimePoint.time_since_epoch()).count(); 181 | } 182 | 183 | /** 184 | @brief ������ ��ȯ�� �Լ� 185 | @return ������ 186 | */ 187 | int CTime::GetYear() const 188 | { 189 | return __mLocalTime.tm_year; 190 | } 191 | 192 | /** 193 | @brief ���� ��ȯ�ϴ� �Լ� 194 | @return �� 195 | */ 196 | int CTime::GetMonth() const 197 | { 198 | return __mLocalTime.tm_mon; 199 | } 200 | 201 | /** 202 | @brief ���� ��ȯ�ϴ� �Լ� 203 | @return �� 204 | */ 205 | int CTime::GetDay() const 206 | { 207 | return __mLocalTime.tm_mday; 208 | } 209 | 210 | /** 211 | @brief �ð��� ��ȯ�ϴ� �Լ� 212 | @return �ð� 213 | */ 214 | int CTime::GetHour() const 215 | { 216 | return __mLocalTime.tm_hour; 217 | } 218 | 219 | /** 220 | @brief ���� ��ȯ�ϴ� �Լ� 221 | @return �� 222 | */ 223 | int CTime::GetMinute() const 224 | { 225 | return __mLocalTime.tm_min; 226 | } 227 | 228 | /** 229 | @brief �ʸ� ��ȯ�ϴ� �Լ� 230 | @return �� 231 | */ 232 | int CTime::GetSecond() const 233 | { 234 | return __mLocalTime.tm_sec; 235 | } 236 | 237 | /** 238 | @brief ������ ��ȯ�ϴ� �Լ� 239 | @details ������ �Ͽ���(0) ~ �����(6)�̴� 240 | @return ���� 241 | */ 242 | EWeekday CTime::GetWeekday() const 243 | { 244 | LB_ASSERT(__mLocalTime.tm_wday >= 0 && __mLocalTime.tm_wday < 7, "Invalid Weekday"); 245 | return static_cast(__mLocalTime.tm_wday); 246 | } 247 | 248 | /** 249 | @brief ������ ���۽ð��� �޴� �Լ� 250 | @return const CTime& ������ ���۽ð� 251 | */ 252 | const CTime& CTime::GetStartTime() 253 | { 254 | return __mStartTime; 255 | } 256 | 257 | Tick CTime::GetSteadyTick() 258 | { 259 | return std::chrono::time_point_cast(std::chrono::steady_clock::now()).time_since_epoch(); 260 | } 261 | 262 | TickCount CTime::GetSteadyTickCount() 263 | { 264 | return GetSteadyTick().count(); 265 | } 266 | 267 | Tick CTime::GetSystemTick() 268 | { 269 | return std::chrono::time_point_cast(std::chrono::system_clock::now()).time_since_epoch(); 270 | } 271 | 272 | TickCount CTime::GetSystemTickCount() 273 | { 274 | return GetSystemTick().count(); 275 | } 276 | 277 | /** 278 | @brief TimePoint�� �̿��Ͽ� ���� ������ �ð����� ������Ʈ�ϴ� �Լ� 279 | */ 280 | void CTime::__UpdateFromTimePoint() 281 | { 282 | using namespace std::chrono; 283 | time_t aTime = std::move(system_clock::to_time_t(__mTimePoint)); 284 | 285 | ::LOCALTIME(&__mLocalTime, &aTime); 286 | __mLocalTime.tm_year += 1900; 287 | } 288 | 289 | /** 290 | @brief LocalTime�� �̿��Ͽ� ���� ������ �ð����� ������Ʈ�ϴ� �Լ� 291 | */ 292 | void CTime::__UpdateFromLocalTime() 293 | { 294 | using namespace std::chrono; 295 | __mLocalTime.tm_year -= 1900; 296 | time_t time = std::move(::mktime(&__mLocalTime)); 297 | 298 | __mLocalTime.tm_year += 1900; 299 | __mTimePoint = system_clock::from_time_t(time); 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /LBUtility/Src/Cpp/LBUtility.cpp: -------------------------------------------------------------------------------- 1 | #include "LBUtility.h" 2 | 3 | namespace LBNet 4 | { 5 | constexpr Version GetLBUVersion() 6 | { 7 | return 20190729u; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBBuffer.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBBuffer.h 3 | @brief LBUtillity의 버퍼관련 헤더 4 | @date 2019-03-29 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | 10 | namespace LBNet 11 | { 12 | /** 13 | @brief 버퍼헤더 클래스 14 | @date 2019-03-29 15 | @auther light8reeze(light8reeze@gmail.com) 16 | */ 17 | #pragma pack(push, 1) 18 | class CBufferHeader 19 | { 20 | public: 21 | CBufferHeader() = default; 22 | ~CBufferHeader() = default; 23 | 24 | public: 25 | Size mDataSize = 0; // 헤더를 제외한 사이즈이다. 26 | }; 27 | #pragma pack(pop) 28 | 29 | /** 30 | @brief 버퍼 클래스 31 | @warning 1.비동기 방식의 enqueue를 사용할때 넣을 데이터는 반드시 CBufferHeader를 상속받아라. 32 | 2.비동기 enqueue는 WriteAddress받아 외부에서 처리하고, 비동기 처리가 끝나면 OnPush를 호출하여 사용한다. 33 | 3.스레드 안정성은 보장하지 않는다. 34 | (서버 패킷 receive(Push)->패킷 처리(pop)를 한스레드에서 하는걸 고려해서 개발) 35 | 4.버퍼의 데이터를 모두 처리후 반드시 Pop를 호출해야 한다. 36 | (Push -> Front -> Pop 순서로 사용한다.) 37 | @date 2019-03-29 38 | @auther light8reeze(light8reeze@gmail.com) 39 | */ 40 | class LBU_EXPORT CBuffer 41 | { 42 | public: 43 | CBuffer(Size pSize); 44 | ~CBuffer(); 45 | 46 | CBuffer(const CBuffer&) = delete; 47 | CBuffer& operator=(const CBuffer&) = delete; 48 | CBuffer& operator=(const CBuffer&&) = delete; 49 | 50 | public: 51 | bool Push(const char* pData, Size pSize); 52 | char* Front(Size& pSize, ErrCode& pErr); 53 | void Pop(); 54 | void Clear(); 55 | bool OnPush(Size pSize); 56 | char* GetWritePointer(); 57 | 58 | Size GetUsingSize() const; 59 | Size GetUsableSize() const; 60 | 61 | Size GetBufferSize(); 62 | 63 | protected: 64 | const Size _mMAX_SIZE; 65 | Size _mUseSize; 66 | int _mReadIndex; 67 | int _mWriteIndex; 68 | char* _mBuffer; 69 | }; 70 | } -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBCharBase.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBCharBase.h 3 | @bfief LBUtillity의 문자열에 필요한 상수, 함수등을 정의해놓은 파일 4 | @date 2019-02-25 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | #include 10 | #ifdef _WIN32 11 | #include 12 | #include 13 | #endif //_WIN32 14 | 15 | namespace LBNet 16 | { 17 | #ifdef _UNICODE 18 | using TChar = wchar_t; 19 | #elif _MBCS 20 | using TChar = char; 21 | #else 22 | #error Using CharSet MBCS or Unicode(define _MBCS or _UNICODE) 23 | #endif //_UNICODE, _MBCS 24 | 25 | /** 26 | @brief Char셋 정의 27 | */ 28 | enum class ECharMode 29 | { 30 | eMBCS = 0, 31 | eUnicode, 32 | eNone 33 | }; 34 | 35 | /** 36 | @brief 현재 프로젝트에서 지원하는 Char타입을 반환한다. 37 | */ 38 | constexpr ECharMode EProjectChar() 39 | { 40 | #ifdef _UNICODE 41 | return ECharMode::eUnicode; 42 | #elif _MBCS 43 | return ECharMode::eMBCS; 44 | #else 45 | #error Using CharSet MBCS or Unicode(define _MBCS or _UNICODE) 46 | #endif //_UNICODE, _MBCS 47 | } 48 | 49 | #ifdef _WIN32 50 | inline std::string WStrToStr(const wchar_t* pPStr, int pNLength) 51 | { 52 | std::string resultStr; 53 | resultStr.reserve(pNLength); 54 | resultStr = CW2A(pPStr); 55 | return std::move(resultStr); 56 | } 57 | 58 | inline std::string WStrToStr(const std::wstring& pWStr) 59 | { 60 | return std::move(WStrToStr(pWStr.c_str(), static_cast(pWStr.length()))); 61 | } 62 | 63 | inline std::wstring StrToWStr(const char* pPStr, int pNLength) 64 | { 65 | std::wstring resultStr; 66 | resultStr.reserve(pNLength); 67 | resultStr = CA2W(pPStr); 68 | return std::move(resultStr); 69 | } 70 | 71 | inline std::wstring StrToWStr(const std::string& pStr) 72 | { 73 | return std::move(StrToWStr(pStr.c_str(), static_cast(pStr.length()))); 74 | } 75 | #endif //_WIN32 76 | 77 | inline Size StrLen(const char* pChar, Size pMaxSize) 78 | { 79 | Size charSize = static_cast(::strnlen_s(pChar, static_cast(pMaxSize))); 80 | LB_ASSERT(charSize >= 0, "Invalid Char"); 81 | 82 | return charSize; 83 | } 84 | 85 | inline Size StrLen(const wchar_t* pChar, Size pMaxSize) 86 | { 87 | Size charSize = static_cast(::wcsnlen_s(pChar, static_cast(pMaxSize))); 88 | LB_ASSERT(charSize >= 0, "Invalid Char"); 89 | 90 | return charSize; 91 | } 92 | 93 | inline bool StrCopy(char* pDest, Size pDestSize, const char* pSrc) 94 | { 95 | int result = ::strcpy_s(pDest, static_cast(pDestSize), pSrc); 96 | LB_ASSERT(result != 0, "strcpy_s Fail!"); 97 | 98 | return (result == 0); 99 | } 100 | 101 | inline bool StrCopy(wchar_t* pDest, Size pDestSize, const wchar_t* pSrc) 102 | { 103 | int result = ::wcscpy_s(pDest, static_cast(pDestSize), pSrc); 104 | LB_ASSERT(result != 0, "strcpy_s Fail!"); 105 | 106 | return (result == 0); 107 | } 108 | 109 | template 110 | inline bool StrCopy(char (&pDest)[TSize], const char* pSrc) 111 | { 112 | int result = ::strcpy_s(pDest, pSrc); 113 | LB_ASSERT(result != 0, "strcpy_s Fail!"); 114 | 115 | return (result == 0); 116 | } 117 | 118 | template 119 | inline bool StrCopy(wchar_t (&pDest)[TSize], const wchar_t* pSrc) 120 | { 121 | int result = ::wcscpy_s(pDest, pSrc); 122 | LB_ASSERT(result != 0, "strcpy_s Fail!"); 123 | 124 | return (result == 0); 125 | } 126 | 127 | inline bool StrConcat(char* pDest, Size pDestSize, const char* pSrc) 128 | { 129 | int result = ::strcat_s(pDest, static_cast(pDestSize), pSrc); 130 | LB_ASSERT(result != 0, "strcat_s Fail!"); 131 | 132 | return (result == 0); 133 | } 134 | 135 | inline bool StrConcat(wchar_t* pDest, Size pDestSize, const wchar_t* pSrc) 136 | { 137 | int result = ::wcscat_s(pDest, static_cast(pDestSize), pSrc); 138 | LB_ASSERT(result != 0, "strcat_s Fail!"); 139 | 140 | return (result == 0); 141 | } 142 | 143 | template 144 | inline bool StrConcat(char (&pDest)[TSize], const char* pSrc) 145 | { 146 | int result = ::strcat_s(pDest, pSrc); 147 | LB_ASSERT(result != 0, "strcpy_s Fail!"); 148 | 149 | return (result == 0); 150 | } 151 | 152 | template 153 | inline bool StrConcat(wchar_t (&pDest)[TSize], const wchar_t* pSrc) 154 | { 155 | int result = ::wcscat_s(pDest, pSrc); 156 | LB_ASSERT(result != 0, "strcpy_s Fail!"); 157 | 158 | return (result == 0); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBEncryption.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBEncyption.h 3 | @brief LBUtillity의 암호화 관련 헤더 4 | @date 2019-04-13 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | 10 | namespace LBNet 11 | { 12 | /** 13 | @brief 암호화 인터페이스 14 | @details 모든 암호화 관련 클래스는 다음 인터페이스를 상속받아 싱글톤 구조로 구현한다. 15 | @date 2019-10-23 16 | @warning 1. 중복으로 상속받아 구현 금지. 17 | 2. 스레드 안전성을 보장하지 못한다. 18 | 3. 싱글톤 인스턴스가 nullptr로 설정될 수도 있다. 19 | (구현된 클래스가 없을시 싱글톤은 nullptr이다) 20 | 4. 하위 클래스에서는 암호화 헤더의 크기를 반드시 설정해야 한다.(_mHeaderSize) 21 | 5. 하위 클래스에서 구현시 반드시 static로 생성해야 한다.(하위에서 동적 할당을 이용한 생성 금지) 22 | @auther light8reeze(light8reeze@gmail.com) 23 | */ 24 | class LBU_EXPORT CEncryptor 25 | { 26 | public: 27 | CEncryptor(); 28 | virtual ~CEncryptor(); 29 | 30 | virtual ErrCode Encrypt(char* pData, Size pSize) = 0; 31 | virtual ErrCode Decrypt(char* pData, Size pSize) = 0; 32 | Size GetHeaderSize(); 33 | 34 | static CEncryptor* Instance(); 35 | 36 | private: 37 | static CEncryptor* __mSingleton; 38 | 39 | protected: 40 | Size _mHeaderSize; 41 | }; 42 | } -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBFile.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | CFile::CFile() : __mIStream(), __mOStream() 4 | { 5 | } 6 | 7 | template 8 | CFile::CFile(TString&& pStr) : __mIStream(), __mOStream() 9 | { 10 | OpenFile(std::forward(pStr)); 11 | } 12 | 13 | CFile::~CFile() 14 | { 15 | if (__mIStream.is_open()) 16 | __mIStream.close(); 17 | 18 | if (__mOStream.is_open()) 19 | __mOStream.close(); 20 | } 21 | 22 | template 23 | bool CFile::OpenFile(TString&& pStr) 24 | { 25 | __mIStream.open(std::forward(pStr)); 26 | __mOStream.open(std::forward(pStr), std::ios::app); 27 | 28 | return IsOpen(); 29 | } 30 | 31 | template 32 | CFile& CFile::operator>>(TArgs& pArgs) const 33 | { 34 | __mIStream >> pArgs; 35 | return *this; 36 | } 37 | 38 | template 39 | CFile& CFile::operator<<(TArgs pArgs) 40 | { 41 | __mOStream << pArgs; 42 | return *this; 43 | } 44 | 45 | template<> 46 | CFile& CFile::operator<<(CFile::__EndLine pArgs) 47 | { 48 | return (pArgs)(*this); 49 | } 50 | 51 | bool CFile::IsOpen() 52 | { 53 | return (__mIStream.is_open() && __mOStream.is_open()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBFile.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBFile.h 3 | @brief LBUtillity의 파일처리 관련 헤더 4 | @date 2019-07-20 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace LBNet 16 | { 17 | /** 18 | @brief 파일IO 클래스 19 | @warnning 멀티바이트 코드 20 | @date 2019-07-20 21 | @auther light8reeze(light8reeze@gmail.com) 22 | */ 23 | class CFile 24 | { 25 | private: 26 | using __EndLine = CFile& (*)(CFile&); 27 | using __OFStream = std::ofstream; 28 | using __IFStream = std::ifstream; 29 | 30 | public: 31 | CFile(); 32 | template 33 | CFile(TString&& pStr); 34 | ~CFile(); 35 | 36 | template 37 | bool OpenFile(TString&& pStr); 38 | template 39 | CFile& operator>>(TArgs& pArgs) const; 40 | template 41 | CFile& operator<<(TArgs pArgs); 42 | 43 | bool IsOpen(); 44 | 45 | public: 46 | static CFile& endl(CFile& out) 47 | { 48 | out << "\n"; 49 | return out; 50 | } 51 | 52 | private: 53 | __IFStream __mIStream; 54 | __OFStream __mOStream; 55 | }; 56 | } 57 | 58 | #include "LBFile.Inl" 59 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBLocker.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBLocker.h 3 | @brief LBUtillity의 잠금관련 헤더 4 | @date 2019-03-31 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | #include 10 | 11 | namespace LBNet 12 | { 13 | #ifdef _DEBUG 14 | /** 15 | @brief 뮤텍스 클래스 16 | @details std::shared_mutex을 이용한 잠금 클래스(디버그 모드에서만 사용) 17 | @comments shared_lock, unique_lock를 이용하여 Read, Write락 구현을 위해 개발 18 | @date 2019-07-20 19 | @auther light8reeze(light8reeze@gmail.com) 20 | */ 21 | class LBU_EXPORT CSharedMutex 22 | { 23 | public: 24 | CSharedMutex(); 25 | ~CSharedMutex() = default; 26 | 27 | void lock(); 28 | void unlock(); 29 | bool try_lock(); 30 | void lock_shared(); 31 | void unlock_shared(); 32 | bool try_lock_shared(); 33 | 34 | std::thread::id GetOwner() { return __mOwner; } 35 | 36 | private: 37 | #pragma warning(disable : 4251) 38 | std::shared_mutex __mMutex; 39 | DEBUG_CODE(std::thread::id __mOwner{}); 40 | #pragma warning(default : 4251) 41 | }; 42 | #else 43 | using CSharedMutex = std::shared_mutex; 44 | #endif //_DEBUG 45 | 46 | template 47 | using ReadLock = std::shared_lock; 48 | template 49 | using WriteLock = std::unique_lock; 50 | 51 | 52 | /** 53 | @brief Mutex사용 오브젝트 지정 54 | @details Mutex사용 오브젝트 사용법은 다음과 같다. 55 | 1. 클래스내에 LB_LOCKOBJECT(클래스명, Mutex타입명)을 넣는다. 56 | 2. 객체 잠금을 사용할때 {ReadLock 변수명(레퍼런스) or WriteLock 변수명(레퍼런스)}로 사용한다. 57 | @warnning 매크로 사용 후에 접근자를 지정한다.(미지정시 매크로 아래로 protected접근자로 인식된다.) 58 | 59 | @param pClass 등록할 오브젝트 클래스 타입 60 | @param pLockType 등록할 Mutex클래스 타입 61 | @date 2020-05-11 62 | @auther light8reeze(light8reeze@gmail.com) 63 | */ 64 | #define LB_LOCKOBJECT(pClass, pLockType) public:\ 65 | using ReadLock = LBNet::ReadLock;\ 66 | using WriteLock = LBNet::WriteLock;\ 67 | void lock(){ _mLocker.lock(); }\ 68 | void unlock(){ _mLocker.unlock(); }\ 69 | bool try_lock(){ return _mLocker.try_lock(); }\ 70 | void lock_shared(){ _mLocker.lock_shared(); }\ 71 | void unlock_shared(){ _mLocker.unlock_shared(); }\ 72 | bool try_lock_shared(){ return _mLocker.try_lock(); }\ 73 | const pLockType& GetLocker() const { return _mLocker; }\ 74 | protected:\ 75 | pLockType _mLocker; 76 | } 77 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBPool.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | CObjectPool::CObjectPool(Size pSize) : __mIsAlloc(false), __mObjectList(), 5 | __mObjectQueue(), __mUseSize(0), __mPoolSize(pSize) 6 | { 7 | __mObjectList.reserve(pSize); 8 | } 9 | 10 | template 11 | CObjectPool::~CObjectPool() 12 | { 13 | Close(); 14 | } 15 | 16 | template 17 | void CObjectPool::Initialize() 18 | { 19 | LB_ASSERT(__mIsAlloc == false, "Alloc Twice!!"); 20 | 21 | WriteLock aLocker(*this); 22 | 23 | for (int index = 0; index < __mPoolSize; ++index) 24 | { 25 | try 26 | { 27 | TObject* aObject = new TObject; 28 | __mObjectList.push_back(aObject); 29 | __mObjectQueue.push(aObject); 30 | } 31 | catch (std::exception& pException) 32 | { 33 | UNREFERENCED_PARAMETER(pException); 34 | LB_ASSERT(0, "Bad Alloc!!"); 35 | } 36 | } 37 | 38 | __mUseSize = 0; 39 | __mIsAlloc = true; 40 | } 41 | 42 | template 43 | void CObjectPool::Close() 44 | { 45 | WriteLock aLocker(*this); 46 | 47 | if (__mIsAlloc == false) 48 | return; 49 | 50 | while (__mObjectQueue.empty() == false) 51 | { 52 | __mObjectQueue.pop(); 53 | } 54 | 55 | for (auto& aObject : __mObjectList) 56 | SafeDelete(aObject); 57 | 58 | __mIsAlloc = false; 59 | __mUseSize = 0; 60 | } 61 | 62 | template 63 | TObject* CObjectPool::NewObject() 64 | { 65 | LB_ASSERT(__mIsAlloc == true, "Call Initialize First!"); 66 | 67 | TObject* aObject = nullptr; 68 | 69 | { 70 | WriteLock aLocker(*this); 71 | 72 | if (__mUseSize >= GetMaxSize()) 73 | return aObject; 74 | 75 | aObject = __mObjectQueue.front(); 76 | __mObjectQueue.pop(); 77 | ++__mUseSize; 78 | } 79 | 80 | LB_ASSERT(aObject != nullptr, "Invalid!"); 81 | 82 | return aObject; 83 | } 84 | 85 | template 86 | bool CObjectPool::DeleteObject(TObject*& pObject) 87 | { 88 | LB_ASSERT(__mIsAlloc == true, "Call Initialize First!"); 89 | LB_ASSERT(pObject != nullptr, "Delete NullPtr!!"); 90 | 91 | bool aCheckFlag = false; 92 | for (const auto& aPtr : __mObjectList) 93 | { 94 | if (aPtr == pObject) 95 | { 96 | aCheckFlag = true; 97 | break; 98 | } 99 | } 100 | 101 | if (aCheckFlag == false) 102 | return false; 103 | 104 | { 105 | WriteLock aLocker(*this); 106 | 107 | __mObjectQueue.push(pObject); 108 | --__mUseSize; 109 | } 110 | 111 | return true; 112 | } 113 | 114 | template 115 | Size CObjectPool::GetMaxSize() 116 | { 117 | return __mPoolSize; 118 | } 119 | 120 | template 121 | Size CObjectPool::GetUseSize() 122 | { 123 | return __mUseSize; 124 | } 125 | 126 | template 127 | constexpr Size CObjectPool::GetObjectSize() 128 | { 129 | return sizeof(TObject); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBPool.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBPool.h 3 | @brief LBUtillity의 오브젝트 풀관련 헤더 4 | @date 2019-04-10 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include 9 | #include "LBUtility.h" 10 | #include "LBLocker.h" 11 | 12 | namespace LBNet 13 | { 14 | /** 15 | @brief 오브젝트 풀 클래스 16 | @details thread safe 17 | @param TObject 사용할 객체의 타입 18 | @date 2019-04-10 19 | @warning 오브젝트를 받은 후 초기화는 caller가 직접 한다. 20 | @auther light8reeze(light8reeze@gmail.com) 21 | */ 22 | template 23 | class CObjectPool 24 | { 25 | LB_LOCKOBJECT(CObjectPool, CSharedMutex); 26 | 27 | public: 28 | using Type = TObject; 29 | 30 | private: 31 | using __ObjectQueue = std::queue; 32 | using __ObjectList = std::vector; 33 | 34 | public: 35 | CObjectPool(Size pSize); 36 | ~CObjectPool(); 37 | 38 | CObjectPool(const CObjectPool&) = delete; 39 | CObjectPool& operator=(const CObjectPool&) = delete; 40 | 41 | void Initialize(); 42 | void Close(); 43 | TObject* NewObject(); 44 | bool DeleteObject(TObject*& pObject); 45 | 46 | Size GetMaxSize(); 47 | Size GetUseSize(); 48 | constexpr Size GetObjectSize(); 49 | 50 | private: 51 | bool __mIsAlloc; 52 | __ObjectList __mObjectList; 53 | __ObjectQueue __mObjectQueue; 54 | Size __mUseSize; 55 | Size __mPoolSize; 56 | }; 57 | } 58 | 59 | #include "LBPool.Inl" 60 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBProbability.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | static bool CProbability::IsSuccess(TType pPercent) 5 | { 6 | return __IsSuccessImpl(pPercent, std::is_integral>()); 7 | } 8 | 9 | template 10 | static int CProbability::GetChoice(const TVector& pVector) 11 | { 12 | using ProbValue = typename TVector::value_type; 13 | ProbValue aRandom = CRandom::GetRandom(ProbValue(0), ProbValue(100)); 14 | ProbValue aSum = static_cast(0); 15 | int aResult = 0; 16 | 17 | for(const auto& aIter : pVector) 18 | { 19 | ProbValue& aNowProb = (*aIter); 20 | 21 | if (aRandom < aNowProb + aSum) 22 | { 23 | break; 24 | } 25 | 26 | ++aResult; 27 | aSum += aNowProb; 28 | } 29 | 30 | return aResult; 31 | } 32 | 33 | template 34 | static int CProbability::GetChoice(TType (&pArray)[TSize]) 35 | { 36 | TType aRandom = CRandom::GetRandom(TType(0), TType(100)); 37 | TType aSum = static_cast(0); 38 | int aResult = 0; 39 | 40 | for (const auto& aProb : pArray) 41 | { 42 | if (aRandom < aProb + aSum) 43 | { 44 | break; 45 | } 46 | 47 | ++aResult; 48 | aSum += aProb; 49 | } 50 | 51 | return aResult; 52 | } 53 | 54 | template 55 | static bool CProbability::__IsSuccessImpl(TType pPercent, std::true_type) 56 | { 57 | TType aRandom = CRandom::GetRandom(TType(0), TType(100)); 58 | return (aRandom < pPercent) ? true : false; 59 | } 60 | 61 | template 62 | static bool CProbability::__IsSuccessImpl(TType pPercent, std::false_type) 63 | { 64 | TType aRandom = CRandom::GetRandom(TType(0.0), TType(100.0)); 65 | return (aRandom < pPercent) ? true : false; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBProbability.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBProbability.h 3 | @brief LBUtillity의 확률 계산 관련 헤더 4 | @date 2019-07-28 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | #include "LBRandom.h" 10 | #include 11 | 12 | namespace LBNet 13 | { 14 | /** 15 | @brief 확률 계산 클래스 16 | @date 2019-07-28 17 | @auther light8reeze(light8reeze@gmail.com) 18 | */ 19 | class CProbability 20 | { 21 | public: 22 | template 23 | static bool IsSuccess(TType pPercent); 24 | 25 | template 26 | static int GetChoice(const TVector& pVector); 27 | 28 | template 29 | static int GetChoice(TType (&pArray)[TSize]); 30 | 31 | private: 32 | template 33 | static bool __IsSuccessImpl(TType pPercent, std::true_type); 34 | template 35 | static bool __IsSuccessImpl(TType pPercent, std::false_type); 36 | }; 37 | } 38 | 39 | #include "LBProbability.Inl" 40 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBQueue.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | #ifdef _WIN32 4 | template 5 | CWaitableQueue::CWaitableQueue() : __mSemaphore(NULL), __mQueue(), __mMutex() 6 | { 7 | __mSemaphore = ::CreateSemaphore(NULL, 0, 0xFFFFFF, NULL); 8 | LB_ASSERT(__mSemaphore != NULL, "Create Semaphore Error!"); 9 | } 10 | 11 | template 12 | CWaitableQueue::~CWaitableQueue() 13 | { 14 | ::CloseHandle(__mSemaphore); 15 | } 16 | 17 | template 18 | bool CWaitableQueue::Push(TObject& pObject) 19 | { 20 | { 21 | WriteLock aLocker(_mLocker); 22 | __mQueue.push(pObject); 23 | } 24 | 25 | BOOL bResult = ::ReleaseSemaphore(__mSemaphore, 1, NULL); 26 | LB_ASSERT(bResult, "Release Semaphore Error!"); 27 | 28 | return true; 29 | } 30 | 31 | template 32 | bool CWaitableQueue::Pop(TObject& pObject, unsigned long pWaitTime) 33 | { 34 | DWORD dwResult = ::WaitForSingleObject(__mSemaphore, pWaitTime); 35 | 36 | if (dwResult != WAIT_OBJECT_0) 37 | { 38 | if (dwResult != WAIT_TIMEOUT) 39 | { 40 | LB_ASSERT(0, "Invalid Dequeue!"); 41 | } 42 | 43 | return false; 44 | } 45 | 46 | { 47 | WriteLock aLocker(_mLocker); 48 | pObject = __mQueue.front(); 49 | __mQueue.pop(); 50 | } 51 | 52 | return true; 53 | } 54 | #endif //_WIN32 55 | 56 | template 57 | CCircularQueue::CCircularQueue() : __mObjectQueue(nullptr), __mPushIndex(0), 58 | __mPopIndex(0), __mUseSize(0), __mMaxSize(0) 59 | { 60 | } 61 | 62 | template 63 | CCircularQueue::~CCircularQueue() 64 | { 65 | SafeArrayDelete(__mObjectQueue); 66 | } 67 | 68 | template 69 | void CCircularQueue::Initialize(Size pSize) 70 | { 71 | LB_ASSERT(__mObjectQueue == nullptr, "Init Twice"); 72 | 73 | __mObjectQueue = new TObject[pSize]; 74 | __mMaxSize = pSize; 75 | } 76 | 77 | template 78 | bool CCircularQueue::Push(TObject&& pObject) 79 | { 80 | LB_ASSERT(__mObjectQueue != nullptr, "Initialize First"); 81 | LB_ASSERT(__mMaxSize > 0, "Initialize First"); 82 | 83 | if (__mUseSize == __mMaxSize) 84 | return false; 85 | 86 | __mObjectQueue[__mPushIndex] = std::move(pObject); 87 | 88 | if (__mPushIndex == __mPopIndex) 89 | __mPopIndex = __mPushIndex; 90 | 91 | __mPushIndex = (__mPushIndex + 1) % static_cast(__mMaxSize); 92 | ++__mUseSize; 93 | 94 | return true; 95 | } 96 | 97 | template 98 | bool CCircularQueue::Push(TObject& pObject) 99 | { 100 | LB_ASSERT(__mObjectQueue != nullptr, "Initialize First"); 101 | LB_ASSERT(__mMaxSize > 0, "Initialize First"); 102 | 103 | if (__mUseSize == __mMaxSize) 104 | return false; 105 | 106 | __mObjectQueue[__mPushIndex] = pObject; 107 | 108 | if (__mPushIndex == __mPopIndex) 109 | __mPopIndex = __mPushIndex; 110 | 111 | __mPushIndex = (__mPushIndex + 1) % static_cast(__mMaxSize); 112 | ++__mUseSize; 113 | 114 | return true; 115 | } 116 | 117 | 118 | template 119 | TObject& CCircularQueue::Front() 120 | { 121 | LB_ASSERT(__mObjectQueue != nullptr, "Initialize First"); 122 | LB_ASSERT(__mMaxSize > 0, "Initialize First"); 123 | 124 | return __mObjectQueue[__mPopIndex]; 125 | } 126 | 127 | template 128 | void CCircularQueue::Pop() 129 | { 130 | LB_ASSERT(__mObjectQueue != nullptr, "Initialize First"); 131 | LB_ASSERT(__mMaxSize > 0, "Initialize First"); 132 | 133 | if (__mPopIndex == __mPushIndex) 134 | return; 135 | 136 | __mPopIndex = (__mPopIndex + 1) % __mMaxSize; 137 | --__mUseSize; 138 | } 139 | 140 | template 141 | Size CCircularQueue::GetUseSize() 142 | { 143 | LB_ASSERT(__mObjectQueue != nullptr, "Initialize First"); 144 | LB_ASSERT(__mMaxSize > 0, "Initialize First"); 145 | 146 | return __mUseSize; 147 | } 148 | 149 | template 150 | Size CCircularQueue::GetMaxSize() 151 | { 152 | LB_ASSERT(__mObjectQueue != nullptr, "Initialize First"); 153 | LB_ASSERT(__mMaxSize > 0, "Initialize First"); 154 | 155 | return __mMaxSize; 156 | } 157 | 158 | template 159 | bool CCircularQueue::IsEmpty() 160 | { 161 | LB_ASSERT(__mObjectQueue != nullptr, "Initialize First"); 162 | LB_ASSERT(__mMaxSize > 0, "Initialize First"); 163 | 164 | return (__mUseSize == 0); 165 | } 166 | 167 | template 168 | bool CCircularQueue::IsFull() 169 | { 170 | LB_ASSERT(__mObjectQueue != nullptr, "Initialize First"); 171 | LB_ASSERT(__mMaxSize > 0, "Initialize First"); 172 | 173 | return (__mUseSize == __mMaxSize); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBQueue.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBQueue.h 3 | @brief LBUtillity의 오브젝트 큐 관련 헤더 4 | @date 2019-04-21 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | #include "LBLocker.h" 10 | 11 | #ifdef _WIN32 12 | #include 13 | #endif //_WIN32 14 | 15 | namespace LBNet 16 | { 17 | /** 18 | @brief 오브젝트 큐 클래스 19 | @details 세마포어를 이용한 큐 클래스. 20 | @param TObject 사용할 객체의 타입 21 | @date 2019-04-21 22 | @auther light8reeze(light8reeze@gmail.com) 23 | */ 24 | template 25 | class CWaitableQueue 26 | { 27 | LB_LOCKOBJECT(CWaitableQueue, LBNet::CSharedMutex); 28 | 29 | private: 30 | using __ObjectQueue = std::queue; 31 | 32 | public: 33 | CWaitableQueue(); 34 | ~CWaitableQueue(); 35 | 36 | CWaitableQueue(const CWaitableQueue&) = delete; 37 | CWaitableQueue& operator=(const CWaitableQueue&) = delete; 38 | 39 | bool Push(TObject& pObject); 40 | bool Pop(TObject& pObject, unsigned long pWaitTime = 0); 41 | 42 | private: 43 | #ifdef _WIN32 44 | HANDLE __mSemaphore; 45 | #endif //_WIN32 46 | __ObjectQueue __mQueue; 47 | }; 48 | 49 | /** 50 | @brief 원형 큐 클래스 51 | @param TObject 사용할 객체의 타입 52 | @warning 스레드 안정성은 보장하지 않는다. 53 | @date 2020-01-18 54 | @auther light8reeze(light8reeze@gmail.com) 55 | */ 56 | template 57 | class CCircularQueue 58 | { 59 | public: 60 | CCircularQueue(); 61 | ~CCircularQueue(); 62 | 63 | CCircularQueue(const CCircularQueue&) = delete; 64 | CCircularQueue& operator=(const CCircularQueue&) = delete; 65 | 66 | void Initialize(Size pSize); 67 | bool Push(TObject&& pObject); 68 | bool Push(TObject& pObject); 69 | TObject& Front(); 70 | void Pop(); 71 | Size GetUseSize(); 72 | Size GetMaxSize(); 73 | bool IsEmpty(); 74 | bool IsFull(); 75 | 76 | private: 77 | TObject* __mObjectQueue; 78 | int __mPushIndex; 79 | int __mPopIndex; 80 | Size __mUseSize; 81 | Size __mMaxSize; 82 | }; 83 | } 84 | 85 | #include "LBQueue.Inl" 86 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBRandom.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | template 4 | inline TType CRandom::GetRandom(TType pMin, TType pMax) 5 | { 6 | return __GetRandomImpl(pMin, pMax, std::is_integral>()) % pMax; 7 | } 8 | 9 | template 10 | inline TType CRandom::__GetRandomImpl(TType pMin, TType pMax, std::true_type) 11 | { 12 | std::random_device aDevice; 13 | MTEngine aMTEngine(aDevice()); 14 | std::uniform_int_distribution aDist(pMin, pMax); 15 | 16 | return aDist(aMTEngine); 17 | } 18 | 19 | template 20 | inline TType CRandom::__GetRandomImpl(TType pMin, TType pMax, std::false_type) 21 | { 22 | std::random_device aDevice; 23 | MTEngine aMTEngine(aDevice()); 24 | std::uniform_real_distribution aDist(pMin, pMax); 25 | 26 | return aDist(aMTEngine); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBRandom.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBRandom.h 3 | @brief LBUtillity의 난수 발생 관련 헤더 4 | @date 2019-07-28 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | #include 10 | 11 | namespace LBNet 12 | { 13 | #ifdef X86 14 | using MTEngine = std::mt19937; 15 | #elif X64 16 | using MTEngine = std::mt19937_64; 17 | #endif //X86 18 | 19 | /** 20 | @brief 랜덤 클래스 21 | @comment C++11의 메르센 트위스터 엔진을 사용하여 구현 22 | @date 2019-07-28 23 | @auther light8reeze(light8reeze@gmail.com) 24 | */ 25 | class CRandom 26 | { 27 | public: 28 | template 29 | static TType GetRandom(TType pMin = std::numeric_limits::min(), TType pMax = std::numeric_limits::max()); 30 | 31 | private: 32 | template 33 | static TType __GetRandomImpl(TType pMin, TType pMax, std::true_type); 34 | template 35 | static TType __GetRandomImpl(TType pMin, TType pMax, std::false_type); 36 | }; 37 | } 38 | 39 | #include "LBRandom.Inl" 40 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBString.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | #pragma region CString 4 | template 5 | CString::CString() : __mStr(), __mUseSize(0) 6 | { 7 | std::fill(__mStr, __mStr + TSize, 0); 8 | } 9 | 10 | template 11 | template 12 | CString::CString(TString&& pRvalue) 13 | : __mStr(), __mUseSize(0) 14 | { 15 | Assign(std::forward(pRvalue)); 16 | } 17 | 18 | template 19 | template 20 | CString::CString(const TString& pRvalue) 21 | : __mStr(), __mUseSize(0) 22 | { 23 | Assign(pRvalue); 24 | } 25 | 26 | template 27 | template 28 | CString& CString::operator=(TString&& pRvalue) 29 | { 30 | Assign(std::forward(pRvalue)); 31 | return (*this); 32 | } 33 | 34 | template 35 | template 36 | CString& CString::operator+=(TString&& pRvalue) 37 | { 38 | Append(std::forward(pRvalue)); 39 | return (*this); 40 | } 41 | 42 | template 43 | template 44 | CString CString::operator+(TString&& pRvalue) 45 | { 46 | CString aStr; 47 | aStr.Append(GetCStr()); 48 | aStr.Append(pRvalue); 49 | 50 | return aStr; 51 | } 52 | 53 | template 54 | void CString::Assign(TCharSet*&& pStr) 55 | { 56 | if (pStr == nullptr) 57 | return; 58 | 59 | Size aLength = static_cast(StrLen(pStr, TSize - 1)); 60 | std::move(pStr, pStr + aLength + 1, __mStr); 61 | __mStr[aLength] = '\0'; 62 | __mUseSize = (aLength + 1); 63 | } 64 | 65 | template 66 | void CString::Assign(const TCharSet*& pStr) 67 | { 68 | if (pStr == nullptr) 69 | return; 70 | 71 | Size aLength = static_cast(StrLen(pStr, TSize - 1)); 72 | std::copy(pStr, pStr + aLength + 1, __mStr); 73 | __mStr[aLength] = '\0'; 74 | __mUseSize = (aLength + 1); 75 | } 76 | 77 | template 78 | template 79 | void CString::Assign(CString&& pRvalue) 80 | { 81 | if (IsSameAddress(this, &pRvalue)) 82 | return; 83 | 84 | Assign(pRvalue.GetCStr()); 85 | } 86 | 87 | template 88 | template 89 | void CString::Assign(const CString& pRvalue) 90 | { 91 | if (IsSameAddress(this, &pRvalue)) 92 | return; 93 | 94 | Assign(pRvalue.GetCStr()); 95 | } 96 | 97 | template 98 | void CString::Assign(std::basic_string&& pRvalue) 99 | { 100 | Assign(static_cast(pRvalue.data())); 101 | } 102 | 103 | template 104 | void CString::Assign(const std::basic_string& pRvalue) 105 | { 106 | Assign(pRvalue.data()); 107 | } 108 | 109 | template 110 | template 111 | void CString::Assign(TCharSet(&&pRvalue)[TNewSize]) 112 | { 113 | Size aLength = std::min(TNewSize, TSize); 114 | std::move(pRvalue, pRvalue + aLength, __mStr); 115 | __mUseSize = aLength; 116 | } 117 | 118 | template 119 | template 120 | void CString::Assign(const TCharSet(&pRvalue)[TNewSize]) 121 | { 122 | Size aLength = std::min(TNewSize, TSize); 123 | std::copy(pRvalue, pRvalue + aLength, __mStr); 124 | __mUseSize = aLength; 125 | } 126 | 127 | template 128 | void CString::Append(const TCharSet*&& pStr) 129 | { 130 | if (pStr == nullptr) 131 | return; 132 | 133 | Size aLength = static_cast(StrLen(pStr, TSize - __mUseSize - 1)); 134 | std::move(pStr, pStr + aLength, __mStr + __mUseSize - 1); 135 | __mUseSize += aLength; 136 | } 137 | 138 | template 139 | void CString::Append(const TCharSet*& pStr) 140 | { 141 | if (pStr == nullptr) 142 | return; 143 | 144 | Size aLength = static_cast(StrLen(pStr, TSize - __mUseSize)); 145 | std::copy(pStr, pStr + aLength, __mStr + __mUseSize - 1); 146 | __mUseSize += aLength; 147 | } 148 | 149 | template 150 | template 151 | void CString::Append(CString&& pRvalue) 152 | { 153 | if (IsSameAddress(this, &pRvalue)) 154 | return; 155 | 156 | Append(std::forward(pRvalue.GetCStr())); 157 | } 158 | 159 | template 160 | template 161 | void CString::Append(const CString& pRvalue) 162 | { 163 | if (IsSameAddress(this, &pRvalue)) 164 | return; 165 | 166 | Append(std::forward(pRvalue.GetCStr())); 167 | } 168 | 169 | template 170 | void CString::Append(std::basic_string&& pRvalue) 171 | { 172 | Append(std::forward(pRvalue.data())); 173 | } 174 | 175 | template 176 | void CString::Append(const std::basic_string& pRvalue) 177 | { 178 | Append(std::forward(pRvalue.data())); 179 | } 180 | 181 | template 182 | template 183 | void CString::Append(const TCharSet(&&pRvalue)[TNewSize]) 184 | { 185 | Size aLength = std::min(TNewSize, TSize - __mUseSize); 186 | std::move(pRvalue, pRvalue + aLength, __mStr + __mUseSize - 1); 187 | __mUseSize += (aLength - 1); 188 | } 189 | 190 | template 191 | template 192 | void CString::Append(const TCharSet(&pRvalue)[TNewSize]) 193 | { 194 | Size aLength = std::min(TNewSize, TSize - __mUseSize); 195 | std::copy(pRvalue, pRvalue + aLength, __mStr + __mUseSize - 1); 196 | __mUseSize += (aLength - 1); 197 | } 198 | 199 | template 200 | TCharSet& CString::operator[](Size pIndex) 201 | { 202 | if (pIndex >= TSize) 203 | throw std::out_of_range("CString index Out of range"); 204 | 205 | return __mStr[pIndex]; 206 | } 207 | 208 | template 209 | const TCharSet* CString::GetCStr() const 210 | { 211 | return __mStr; 212 | } 213 | 214 | template 215 | constexpr Size CString::GetMaxLength() const 216 | { 217 | return TSize; 218 | } 219 | 220 | template 221 | Size CString::GetLength() const 222 | { 223 | return __mUseSize; 224 | } 225 | #pragma endregion CString 226 | 227 | #pragma region CBufferedString 228 | template 229 | CBufferedString::CBufferedString() : __mStr(nullptr), __mMaxSize(0), __mUseSize(0) 230 | { 231 | } 232 | 233 | template 234 | CBufferedString::CBufferedString(CBufferedString&& pRvalue) 235 | : __mStr(std::move(pRvalue.__mStr)), __mMaxSize(std::move(pRvalue.__mMaxSize)), 236 | __mUseSize(std::move(pRvalue.__mUseSize)) 237 | { 238 | } 239 | 240 | template 241 | CBufferedString::CBufferedString(const CBufferedString& pRvalue) 242 | : __mStr(pRvalue.__mStr), __mMaxSize(pRvalue.__mMaxSize), __mUseSize(pRvalue.__mUseSize) 243 | { 244 | } 245 | 246 | template 247 | CBufferedString::CBufferedString(TCharSet* pBuf, Size pBufSize) 248 | : __mStr(nullptr), __mMaxSize(0), __mUseSize(0) 249 | { 250 | AllocBuffer(pBuf, pBufSize); 251 | } 252 | 253 | template 254 | void CBufferedString::AllocBuffer(TCharSet* pBuf, Size pBufSize) 255 | { 256 | LB_ASSERT(pBuf != nullptr, "Error!"); 257 | 258 | __mStr = pBuf; 259 | __mMaxSize = pBufSize; 260 | __mUseSize = 0; 261 | 262 | std::fill(__mStr, __mStr + __mMaxSize, 0); 263 | } 264 | 265 | template 266 | template 267 | CBufferedString& CBufferedString::operator=(TString&& pRvalue) 268 | { 269 | Assign(std::forward(pRvalue)); 270 | return (*this); 271 | } 272 | 273 | template 274 | template 275 | CBufferedString& CBufferedString::operator+=(TString&& pRvalue) 276 | { 277 | Append(std::forward(pRvalue)); 278 | return (*this); 279 | } 280 | 281 | template 282 | template 283 | CBufferedString CBufferedString::operator+(TString&& pRvalue) 284 | { 285 | CBufferedString aStr; 286 | aStr.Append(GetCStr()); 287 | aStr.Append(pRvalue); 288 | 289 | return aStr; 290 | } 291 | 292 | template 293 | void CBufferedString::Assign(TCharSet*&& pStr) 294 | { 295 | if (pStr == nullptr || __mStr == nullptr) 296 | return; 297 | 298 | if (IsSameAddress(__mStr, pStr)) 299 | return; 300 | 301 | Size aLength = static_cast(StrLen(pStr, GetMaxLength() - 1)); 302 | std::move(pStr, pStr + aLength + 1, __mStr); 303 | __mStr[aLength] = '\0'; 304 | __mUseSize = (aLength + 1); 305 | } 306 | 307 | template 308 | void CBufferedString::Assign(const TCharSet*& pStr) 309 | { 310 | if (pStr == nullptr || __mStr == nullptr) 311 | return; 312 | 313 | if (IsSameAddress(__mStr, const_cast(pStr))) 314 | return; 315 | 316 | Size aLength = static_cast(StrLen(pStr, GetMaxLength() - 1)); 317 | std::copy(pStr, pStr + aLength + 1, __mStr); 318 | __mStr[aLength] = '\0'; 319 | __mUseSize = (aLength + 1); 320 | } 321 | 322 | template 323 | void CBufferedString::Assign(CBufferedString&& pRvalue) 324 | { 325 | if (IsSameAddress(this, &pRvalue)) 326 | return; 327 | 328 | Assign(pRvalue.GetCStr()); 329 | } 330 | 331 | template 332 | void CBufferedString::Assign(const CBufferedString& pRvalue) 333 | { 334 | if (IsSameAddress(this, &pRvalue)) 335 | return; 336 | 337 | Assign(pRvalue.GetCStr()); 338 | } 339 | 340 | template 341 | void CBufferedString::Assign(std::basic_string&& pRvalue) 342 | { 343 | Assign(static_cast(pRvalue.data())); 344 | } 345 | 346 | template 347 | void CBufferedString::Assign(const std::basic_string& pRvalue) 348 | { 349 | Assign(pRvalue.data()); 350 | } 351 | 352 | template 353 | template 354 | void CBufferedString::Assign(TCharSet(&&pRvalue)[TNewSize]) 355 | { 356 | if (__mStr == nullptr) 357 | return; 358 | 359 | Size aLength = std::min(TNewSize, GetMaxLength()); 360 | std::move(pRvalue, pRvalue + aLength, __mStr); 361 | __mUseSize = aLength; 362 | } 363 | 364 | template 365 | template 366 | void CBufferedString::Assign(const TCharSet(&pRvalue)[TNewSize]) 367 | { 368 | if (__mStr == nullptr) 369 | return; 370 | 371 | Size aLength = std::min(TNewSize, GetMaxLength()); 372 | std::copy(pRvalue, pRvalue + aLength, __mStr); 373 | __mUseSize = aLength; 374 | } 375 | 376 | template 377 | void CBufferedString::Append(const TCharSet*&& pStr) 378 | { 379 | if (pStr == nullptr || __mStr == nullptr) 380 | return; 381 | 382 | Size aLength = static_cast(StrLen(pStr, GetMaxLength() - __mUseSize - 1)); 383 | std::move(pStr, pStr + aLength, __mStr + std::max(__mUseSize - 1, 0)); 384 | __mUseSize += aLength; 385 | } 386 | 387 | template 388 | void CBufferedString::Append(const TCharSet*& pStr) 389 | { 390 | if (pStr == nullptr || __mStr == nullptr) 391 | return; 392 | 393 | Size aLength = static_cast(StrLen(pStr, GetMaxLength() - __mUseSize)); 394 | std::copy(pStr, pStr + aLength, __mStr + std::max(__mUseSize - 1, 0)); 395 | __mUseSize += aLength; 396 | } 397 | 398 | template 399 | void CBufferedString::Append(CBufferedString&& pRvalue) 400 | { 401 | if (IsSameAddress(this, &pRvalue)) 402 | return; 403 | 404 | Append(std::forward(pRvalue.GetCStr())); 405 | } 406 | 407 | template 408 | void CBufferedString::Append(const CBufferedString& pRvalue) 409 | { 410 | if (IsSameAddress(this, &pRvalue)) 411 | return; 412 | 413 | Append(std::forward(pRvalue.GetCStr())); 414 | } 415 | 416 | template 417 | void CBufferedString::Append(std::basic_string&& pRvalue) 418 | { 419 | Append(std::forward(pRvalue.data())); 420 | } 421 | 422 | template 423 | void CBufferedString::Append(const std::basic_string& pRvalue) 424 | { 425 | Append(std::forward(pRvalue.data())); 426 | } 427 | 428 | template 429 | template 430 | void CBufferedString::Append(const TCharSet(&&pRvalue)[TNewSize]) 431 | { 432 | if (__mStr == nullptr) 433 | return; 434 | 435 | Size aLength = std::min(TNewSize, GetMaxLength() - __mUseSize); 436 | std::move(pRvalue, pRvalue + aLength, __mStr + std::max(__mUseSize - 1, 0)); 437 | __mUseSize += (aLength - 1); 438 | } 439 | 440 | template 441 | template 442 | void CBufferedString::Append(const TCharSet(&pRvalue)[TNewSize]) 443 | { 444 | if (__mStr == nullptr) 445 | return; 446 | 447 | Size aLength = std::min(TNewSize, GetMaxLength() - __mUseSize); 448 | std::copy(pRvalue, pRvalue + aLength, __mStr + std::max(__mUseSize - 1, 0)); 449 | __mUseSize += (aLength - 1); 450 | } 451 | 452 | template 453 | TCharSet& CBufferedString::operator[](Size pIndex) 454 | { 455 | if (pIndex >= GetMaxLength()) 456 | throw std::out_of_range("CString index Out of range"); 457 | 458 | return __mStr[pIndex]; 459 | } 460 | 461 | template 462 | const TCharSet* CBufferedString::GetCStr() const 463 | { 464 | return __mStr; 465 | } 466 | 467 | template 468 | Size CBufferedString::GetMaxLength() const 469 | { 470 | return __mMaxSize; 471 | } 472 | 473 | template 474 | Size CBufferedString::GetLength() const 475 | { 476 | return __mUseSize; 477 | } 478 | #pragma endregion CBufferedString 479 | } 480 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBString.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBString.h 3 | @bfief LBUtillity의 문자열 클래스 정의 4 | @date 2019-02-27 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBCharBase.h" 9 | 10 | namespace LBNet 11 | { 12 | /** 13 | @bfief 정적 String클래스(힙 메모리를 사용하지 않는다.) 14 | @param TCharSet 문자열 타입(char, wchar_t) 15 | @param TSize 문자열 메모리 크기 16 | @warning 문자열 대입, 추가의 경우 정해진 크기까지만 들어간다.(TSize - 1) 17 | @date 2019-12-26 18 | @auther light8reeze(light8reeze@gmail.com) 19 | */ 20 | template 21 | class CString 22 | { 23 | public: 24 | using Type = TCharSet; 25 | 26 | public: 27 | CString(); 28 | template 29 | CString(TString&& pRvalue); 30 | template 31 | CString(const TString& pRvalue); 32 | ~CString() = default; 33 | 34 | template 35 | CString& operator=(TString&& pRvalue); 36 | template 37 | CString& operator+=(TString&& pRvalue); 38 | template 39 | CString operator+(TString&& pRvalue); 40 | 41 | void Assign(TCharSet*&& pStr); 42 | void Assign(const TCharSet*& pStr); 43 | template 44 | void Assign(CString&& pRvalue); 45 | template 46 | void Assign(const CString& pRvalue); 47 | void Assign(std::basic_string&& pRvalue); 48 | void Assign(const std::basic_string& pRvalue); 49 | template 50 | void Assign(TCharSet(&&pRvalue)[TNewSize]); 51 | template 52 | void Assign(const TCharSet(&pRvalue)[TNewSize]); 53 | 54 | void Append(const TCharSet*&& pStr); 55 | void Append(const TCharSet*& pStr); 56 | template 57 | void Append(CString&& pRvalue); 58 | template 59 | void Append(const CString& pRvalue); 60 | void Append(std::basic_string&& pRvalue); 61 | void Append(const std::basic_string& pRvalue); 62 | template 63 | void Append(const TCharSet(&&pRvalue)[TNewSize]); 64 | template 65 | void Append(const TCharSet(&pRvalue)[TNewSize]); 66 | 67 | TCharSet& operator[](Size pIndex); 68 | 69 | const TCharSet* GetCStr() const; 70 | 71 | constexpr Size GetMaxLength() const; 72 | Size GetLength() const; 73 | 74 | private: 75 | TCharSet __mStr[TSize]; 76 | Size __mUseSize; 77 | }; 78 | 79 | /** 80 | @bfief �޸� ���� ������ ��Ʈ�� Ŭ����. 81 | �޸� ���� �����͸� �ܺο��� �޾� ��� �����ϴ�. 82 | @param TCharSet ���ڿ� Ÿ��(char, wchar_t) 83 | @comment std::string�� ����, ���� �� �� �޸𸮸� �̿��Ѵ�. 84 | �޸� ����ȭ�� ���� ���� ������ �޸𸮸� �̿��� string�� �����Ѵ�. 85 | @warning String�� ����� �޸� ���۴� ȣ���ڰ� ���� �����Ѵ�. 86 | @date 2019-12-26 87 | @auther light8reeze(light8reeze@gmail.com) 88 | */ 89 | template 90 | class CBufferedString 91 | { 92 | public: 93 | using Type = TCharSet; 94 | 95 | public: 96 | CBufferedString(); 97 | CBufferedString(CBufferedString&& pRvalue); 98 | CBufferedString(const CBufferedString& pRvalue); 99 | CBufferedString(TCharSet* pBuf, Size pBufSize); 100 | ~CBufferedString() = default; 101 | 102 | void AllocBuffer(TCharSet* pBuf, Size pBufSize); 103 | 104 | template 105 | CBufferedString& operator=(TString&& pRvalue); 106 | template 107 | CBufferedString& operator+=(TString&& pRvalue); 108 | template 109 | CBufferedString operator+(TString&& pRvalue); 110 | 111 | void Assign(TCharSet*&& pStr); 112 | void Assign(const TCharSet*& pStr); 113 | void Assign(CBufferedString&& pRvalue); 114 | void Assign(const CBufferedString& pRvalue); 115 | void Assign(std::basic_string&& pRvalue); 116 | void Assign(const std::basic_string& pRvalue); 117 | template 118 | void Assign(TCharSet(&&pRvalue)[TNewSize]); 119 | template 120 | void Assign(const TCharSet(&pRvalue)[TNewSize]); 121 | 122 | void Append(const TCharSet*&& pStr); 123 | void Append(const TCharSet*& pStr); 124 | void Append(CBufferedString&& pRvalue); 125 | void Append(const CBufferedString& pRvalue); 126 | void Append(std::basic_string&& pRvalue); 127 | void Append(const std::basic_string& pRvalue); 128 | template 129 | void Append(const TCharSet(&&pRvalue)[TNewSize]); 130 | template 131 | void Append(const TCharSet(&pRvalue)[TNewSize]); 132 | 133 | TCharSet& operator[](Size pIndex); 134 | 135 | const TCharSet* GetCStr() const; 136 | 137 | Size GetMaxLength() const; 138 | Size GetLength() const; 139 | 140 | private: 141 | TCharSet* __mStr; 142 | Size __mMaxSize; 143 | Size __mUseSize; 144 | }; 145 | } 146 | 147 | #include "LBString.Inl" 148 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBTime.Inl: -------------------------------------------------------------------------------- 1 | namespace LBNet 2 | { 3 | /** 4 | @brief CTime의 +=연산자 5 | */ 6 | template 7 | inline CTime& CTime::operator+=(const std::chrono::duration& pTime) 8 | { 9 | __mTimePoint += pTime; 10 | __UpdateFromTimePoint(); 11 | 12 | return (*this); 13 | } 14 | 15 | /** 16 | @brief CTime의 -=연산자 17 | */ 18 | template 19 | inline CTime& CTime::operator-=(const std::chrono::duration& pTime) 20 | { 21 | __mTimePoint -= pTime; 22 | __UpdateFromTimePoint(); 23 | 24 | return (*this); 25 | } 26 | 27 | /** 28 | @brief CTime의 +연산자 29 | */ 30 | template< class Rep, class Period> 31 | inline CTime CTime::operator+(const std::chrono::duration& pTime) 32 | { 33 | CTime aTime; 34 | TimePoint point = __mTimePoint + pTime; 35 | aTime.SetTimePoint(std::move(point)); 36 | 37 | return aTime; 38 | } 39 | 40 | /** 41 | @brief CTime의 -연산자 42 | */ 43 | template 44 | inline CTime CTime::operator-(const std::chrono::duration& pTime) 45 | { 46 | CTime time; 47 | TimePoint point = __mTimePoint - pTime; 48 | time.SetTimePoint(std::move(point)); 49 | 50 | return time; 51 | } 52 | } -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBTime.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBTime.h 3 | @brief LBUtillity의 시간관련 헤더 4 | @date 2019-03-16 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include "LBUtility.h" 9 | #include 10 | 11 | /** 12 | @brief 빌드하는 OS에 맞춰 localtime함수를 정의한다. 13 | */ 14 | #ifdef _WIN32 15 | #define LOCALTIME(TM, time) localtime_s((TM), (time)) 16 | #elif __linux__ 17 | #define LOCALTIME(TM, time) localtime_r((time), (TM)) 18 | #endif //_WIN32 19 | 20 | namespace LBNet 21 | { 22 | /** 23 | @brief 요일 Enum정의 24 | @warning struct tm의 tm_wday값과 맞춰야 한다.(0:일요일 ~ 6:토요일) 25 | */ 26 | enum class EWeekday 27 | { 28 | eSunday = 0, 29 | eMonday, 30 | eTuesday, 31 | eWednesday, 32 | eThursday, 33 | eFriday, 34 | eSaturday 35 | }; 36 | 37 | /** 38 | @brief LBUtillity의 시간 클래스 39 | @details 특정 시간을 표현하는 클래스, std::chrono를 기반으로 구현 Get, Set은 struct tm을 증감은 TimePoint를 이용한다 40 | @date 2019-03-16 41 | @auther light8reeze(light8reeze@gmail.com) 42 | */ 43 | class LBU_EXPORT CTime 44 | { 45 | private: 46 | using Clock = std::chrono::system_clock; 47 | using TimePoint = Clock::time_point; 48 | 49 | public: 50 | CTime(); 51 | CTime(const CTime&) = default; 52 | ~CTime() = default; 53 | 54 | CTime& operator=(const CTime&) = default; 55 | CTime& operator+=(const CTime& pTime); 56 | CTime& operator-=(const CTime& pTime); 57 | CTime operator+(const CTime& pTime); 58 | CTime operator-(const CTime& pTime); 59 | 60 | template 61 | CTime& operator+=(const std::chrono::duration& pTime); 62 | template 63 | CTime& operator-=(const std::chrono::duration& pTime); 64 | template 65 | CTime operator+(const std::chrono::duration& pTime); 66 | template 67 | CTime operator-(const std::chrono::duration& pTime); 68 | 69 | public: 70 | void SetNow(); 71 | void SetYear(int pYear); 72 | void SetMonth(int pMonth); 73 | void SetDay(int pDay); 74 | void SetHour(int pHour); 75 | void SetMinute(int pMinute); 76 | void SetSecond(int pSecond); 77 | void SetTimePoint(TimePoint pTimePoint); 78 | 79 | TimePoint GetTimePoint() const; 80 | Tick ToTick() const; 81 | TickCount ToTickCount() const; 82 | int GetYear() const; 83 | int GetMonth() const; 84 | int GetDay() const; 85 | int GetHour() const; 86 | int GetMinute() const; 87 | int GetSecond() const; 88 | EWeekday GetWeekday() const; 89 | 90 | static const CTime& GetStartTime(); 91 | static Tick GetSteadyTick(); 92 | static TickCount GetSteadyTickCount(); 93 | static Tick GetSystemTick(); 94 | static TickCount GetSystemTickCount(); 95 | 96 | private: 97 | void __UpdateFromTimePoint(); 98 | void __UpdateFromLocalTime(); 99 | 100 | private: 101 | static const CTime __mStartTime; 102 | 103 | #pragma warning(disable : 4251) 104 | TimePoint __mTimePoint; 105 | #pragma warning(default : 4251) 106 | struct tm __mLocalTime; 107 | }; 108 | } 109 | 110 | #include "LBTime.Inl" 111 | -------------------------------------------------------------------------------- /LBUtility/Src/Inc/LBUtility.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file LBUtility.h 3 | @brief LBUtility를 사용하기 위해 필요한 설정 헤더파일 4 | @date 2019-02-17 5 | @auther light8reeze(light8reeze@gmail.com) 6 | */ 7 | #pragma once 8 | #include 9 | 10 | //#define DEVELOP_MODE 11 | 12 | #ifdef WIN32 13 | #define X86 14 | #endif //WIN32 15 | 16 | /** 17 | @brief windows의 min, max를 사용하지 않고 std의 min, max를 사용한다. 18 | */ 19 | #ifndef NOMINMAX 20 | #define NOMINMAX 21 | #endif 22 | 23 | #ifdef _WIN32 24 | ///////////////////////////////////////////////////////////////////////// 25 | // SDKDDKVer.h를 포함하면 최고 수준의 가용성을 가진 Windows 플랫폼이 정의됩니다. 26 | // 이전 Windows 플랫폼에 대해 응용 프로그램을 빌드하려는 경우에는 SDKDDKVer.h를 포함하기 전에 27 | // WinSDKVer.h를 포함하고 _WIN32_WINNT 매크로를 지원하려는 플랫폼으로 설정하십시오. 28 | #include 29 | ///////////////////////////////////////////////////////////////////////// 30 | #endif //_WIN32 31 | 32 | #include 33 | #include 34 | 35 | /** 36 | @brief std::chrono_literals 사용 정의 37 | */ 38 | #include 39 | using namespace std::chrono_literals; 40 | 41 | /** 42 | @brief DllExport 관련 매크로 43 | @details dll을 받아 어플리케이션을 구현할 때에는 LBUtillity.h를 정의하기 전에 LOAD_LBUTILL매크로를 정의한다. 44 | */ 45 | #if __linux__ 46 | #define LBU_EXPORT __attribute__((visibility("default"))) 47 | #define LBU_EXPORT_TEMPLATE(pClass) extern template class LBU_EXPORT pClass 48 | #elif _WIN32 49 | #ifdef LOAD_LBUTILL 50 | #define LBU_EXPORT __declspec(dllimport) 51 | #define LBU_EXPORT_TEMPLATE(pClass) extern template class LBU_EXPORT pClass 52 | #else 53 | #define LBU_EXPORT __declspec(dllexport) 54 | #define LBU_EXPORT_TEMPLATE(pClass) template class LBU_EXPORT pClass 55 | #endif //LOAD_LBUTILL 56 | #endif // _WIN32 57 | 58 | /** 59 | @brief assert 관련 매크로 60 | @param pExp 검증할 표현식 61 | @param pMsg assert발생시 출력할 메세지 62 | */ 63 | #define LB_ASSERT(pExp, pMsg) assert((pExp) && (pMsg)) 64 | 65 | /** 66 | @brief 디버그 모드에만 넣을 코드 매크로 (Release모드에선 제외) 67 | @param pExp 디버그에 사용할 코드 68 | */ 69 | #ifdef _DEBUG 70 | #define DEBUG_CODE(pExp) pExp 71 | #else 72 | #define DEBUG_CODE(pExp) 73 | #endif //_DEBUG 74 | 75 | namespace LBNet 76 | { 77 | /** 78 | @brief LBEngine에서 사용하는 크기 타입 정의 79 | */ 80 | using Size = unsigned short; 81 | 82 | /** 83 | @brief LBEngine에서 사용하는 기본 시간 단위 정의 84 | */ 85 | using Tick = std::chrono::duration; 86 | using TickCount = Tick::rep; 87 | 88 | /** 89 | @brief Enum을 타입의 값으로 변환해주는 함수 90 | @param TEnum 변환할 Enum값 91 | @return auto 변환된 Enum값 92 | */ 93 | template 94 | constexpr auto UnderLying(TEnum e) 95 | { 96 | return static_cast::type>(e); 97 | } 98 | 99 | /** 100 | @brief 두 포인터가 같은 주소인지 검사하는 함수 101 | @param T1 비교할 포인터 타입 102 | @param T2 비교할 포인터 타입 103 | @warning 혼동을 피하기 위해 두 인자를 모두 포인터타입을 넣어준다. 104 | 1. 포인터, 일반 변수를 섞어사용할 경우 버그가 발생할 가능성이 높다. 105 | (ex1 : T1 = int*, T2 = void*) => 포인터비교가 맞게 실행됨 106 | (ex2 : T1 = int*, T2 = char) => 포인터비교가 맞게 실행되지 않음 107 | 2. const 포인터의 경우 const를 제거하여 인자로 넣어야 한다. 108 | @return bool 두 포인터가 같은 주소이면 true 아니면 false 109 | */ 110 | template 111 | inline bool IsSameAddress(T1 pT1, T2 pT2) 112 | { 113 | static_assert(std::is_pointer::value && std::is_pointer::value); 114 | using Non_cvT1 = std::remove_cv_t; 115 | using Non_cvT2 = std::remove_cv_t; 116 | 117 | return (reinterpret_cast(const_cast(pT1)) 118 | == reinterpret_cast(const_cast(pT2))); 119 | } 120 | 121 | /** 122 | @brief LBUtillity의 버전을 받는 함수 123 | @return Version LBUtillity의 버전 124 | */ 125 | using Version = unsigned int; 126 | constexpr Version LBU_EXPORT GetLBUVersion(); 127 | 128 | /** 129 | @brief 특정 포인터를 할당 해제하는 함수 130 | @param TType 삭제할 포인터 자료형 131 | @param TType& 삭제할 포인터 132 | @warning TType는 반드시 포인터여야 한다. 133 | */ 134 | template 135 | inline void SafeDelete(TType& pObject) 136 | { 137 | static_assert(std::is_pointer::value); 138 | 139 | delete pObject; 140 | pObject = nullptr; 141 | } 142 | 143 | /** 144 | @brief 특정 포인터를 할당 해제하는 함수(배열) 145 | @param TType 삭제할 포인터 자료형 146 | @param TType& 삭제할 포인터 147 | @warning TType는 반드시 포인터여야 한다. 148 | */ 149 | template 150 | inline void SafeArrayDelete(TType& pObject) 151 | { 152 | static_assert(std::is_pointer::value); 153 | 154 | delete[] pObject; 155 | pObject = nullptr; 156 | } 157 | 158 | /** 159 | @brief 에러코드 타입 160 | */ 161 | using ErrCode = std::size_t; 162 | } 163 | 164 | /** 165 | @brief 에러코드 등록 매크로 166 | @comment pErr에 사용할 변수명을 넣는다. 167 | */ 168 | #define LB_ERRCODE(pErr) const LBNet::ErrCode pErr = std::hash{}(#pErr) -------------------------------------------------------------------------------- /README(en).md: -------------------------------------------------------------------------------- 1 | # LBEngine 2 | 3 | LBEngine is easy game server engine using C++ with boost.asio. It's implemented by using C++17, asynchronous IO, and multithread base. It can be work in windows(Visual Studio 2017 or later) and support TCP 4 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/480aabb761ba4735a2763dd6dc816467)](https://www.codacy.com?utm_source=github.com&utm_medium=referral&utm_content=light8reeze/LBEngine&utm_campaign=Badge_Grade) 5 | 6 | # Feature 7 | 8 | Easy to develop game server 9 | Using asynchronous IO 10 | Support multithread 11 | 12 | # Start 13 | 14 | # Example 15 | 16 | # License 17 | 18 | Copyright © 2019-2020 [light8reeze](http://www.github.com/light8reeze). -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LBEngine 2 | 3 | LBEngine는 C++ Boost.Asio 소켓을 이용하여 개발한 게임 서버 엔진입니다. C++17을 이용했고, 비동기 멀티쓰레드 구조로 작동합니다. 현재는 Windows만 지원합니다. 4 | 5 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/480aabb761ba4735a2763dd6dc816467)](https://www.codacy.com?utm_source=github.com&utm_medium=referral&utm_content=light8reeze/LBEngine&utm_campaign=Badge_Grade) 6 | 7 | ## Feature 8 | 9 | 게임서버 개발에 쉽게 사용이 가능합니다. 10 | 비동기 방식의 IO 11 | 멀티쓰레드 지원 12 | 13 | ## Environment 14 | 15 | Support Windows OS Only 16 | Visual Studio 2017 or later 17 | boost Lib 1.70 18 | 19 | ## How To Use 20 | 21 | ### GameObject 22 | 23 | `CGameObject`는 서버 접속하는 유저에게 할당되는 기본 오브젝트입니다. 사용자는 해당 클래스를 상속받아서 클래스를 구현하여 게임에 필요한 정보를 저장하고 플레이어 로직을 구현합니다. 24 | 25 | 26 | 27 | ### Config 28 | 29 | `CConfig`클래스는 서버 구동에 필요한 정보를 저장하는 클래스입니다. 사용자는 서버 설정을 `CConfig`클래스에서 설정합니다. 또한 Application에서 추가로 설정 정보가 필요한 경우 `CConfig`클래스를 상속받아 확장합니다. 30 | 31 | 32 | 33 | ### GameServer 34 | 35 | `CGameServer`는 게임서버의 메인 로직 클래스입니다. 템플릿 인자는 사용자가 구현한 `CGameObject`클래스를 넣습니다. 사용자는 Game Server Application 구현시 해당 클래스를 상속받아서 구현합니다. 사용자가 구현 가능한 함수는 3개가 있습니다. 36 | 37 | - `Initialize()` : `Initialize()`함수는 서버의 초기화를 담당하는 함수입니다. 사용자는 해당 함수 구현시 `__super::Initialize()` 함수를 먼저 호출 후 Application에 필요한 초기화 로직을 작성합니다. 38 | - `LazyInitialize()` : `LazyInitialize()` 함수는 초기화 단계 이후 서버 실행 전 마지막으로 필요한 정보를 초기화 하는 함수입니다. 사용자는 해당 함수 구현시 `__super::Initialize()` 함수를 먼저 호출 후 Application에 필요한 마지막 초기화 로직을 작성합니다. 39 | - `Close()` : `Close()` 함수는 서버가 종료되기전에 자원 해제 등의 정리를 담당하는 함수입니다. 사용자는 해당 함수 구현시 Application에 필요한 정리 로직을 작성 후 `__super::Close()` 함수를 호출합니다. 40 | 41 | `CGameServer`클래스 구현 후 사용자는 `main` 함수에서 해당 클래스를 생성하고 `SetConfig`, `Initialize`, `LazyInitialize`, `Run`, `Close` 함수를 순서대로 호출합니다. 42 | 43 | 44 | 45 | ### Packet Handler 46 | 47 | 패킷 처리 이벤트 등록은 `CTcpHandler`클래스를 통해 등록합니다. 패킷 처리 함수는 `std::function&)>` 형식으로 사용합니다. 위와 같은 형식으로 함수, 람다를 구현하고 `CTcpHandler::Register`함수를 사용하여 패킷 번호와 함께 추가합니다. 패킷 형식은 ` CPacketHeader`클래스를 상속받은 형식으로 사용합니다. 48 | 49 | 50 | 51 | ### Example 52 | 53 | 기본 사용 예제는 [Test Server](TestServer/)프로젝트를 참고하시기 바랍니다. 54 | 55 | 56 | 57 | ## Document 58 | 59 | [Project Reference](Doc/Project-Reference.md) 60 | [Project Todo List](Doc/Project-Todo.md) 61 | 62 | 63 | 64 | ## License 65 | 66 | Copyright © 2019-2020 [light8reeze](http://www.github.com/light8reeze). 67 | 68 | -------------------------------------------------------------------------------- /TestServer/AppDefines.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/TestServer/AppDefines.h -------------------------------------------------------------------------------- /TestServer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2) 2 | 3 | project(TestServer) 4 | 5 | set(CMAKE_CONFIGURATION_TYPES "Debug;Release" 6 | CACHE STRING "Configuration types" FORCE) 7 | 8 | set(BOOST_DIR "C:/boost_1_70_0") 9 | 10 | INCLUDE_DIRECTORIES(include Src/Inc) 11 | INCLUDE_DIRECTORIES(include ../LBServer/Src/Inc) 12 | INCLUDE_DIRECTORIES(include ../LBUtility/Src/Inc) 13 | INCLUDE_DIRECTORIES(include BOOST_DIRECTORY) 14 | 15 | add_executable(TestServer 16 | AppDefines.h 17 | CTestServer.cpp 18 | CTestServer.h 19 | main.cpp 20 | ) 21 | # Output file name 22 | set_target_properties(TestServer 23 | PROPERTIES 24 | OUTPUT_NAME_DEBUG TestServerD_x64 25 | OUTPUT_NAME_RELEASE TestServer_x64 26 | ) 27 | 28 | # Preprocessor definitions 29 | target_compile_definitions(TestServer PRIVATE 30 | $<$:_UNICODE;X64;_DEBUG;_CONSOLE> 31 | $<$:_UNICODE;X64;NDEBUG;_CONSOLE> 32 | ) 33 | 34 | # SDL check 35 | if (MSVC) 36 | target_compile_options(TestServer PRIVATE 37 | "$<$:/sdl>" 38 | "$<$:/sdl>" 39 | ) 40 | endif () 41 | 42 | # Minimal rebuild 43 | if (MSVC) 44 | target_compile_options(TestServer PRIVATE 45 | "$<$:/Gm->" 46 | "$<$:/Gm->" 47 | ) 48 | endif () 49 | 50 | # Precompiled header files 51 | if (MSVC) 52 | target_compile_options(TestServer PRIVATE 53 | "" 54 | ) 55 | endif () 56 | -------------------------------------------------------------------------------- /TestServer/CTestServer.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/light8reeze/LBEngine/88eea45a25182ab412640f141f739dfc6c48ca2e/TestServer/CTestServer.cpp -------------------------------------------------------------------------------- /TestServer/CTestServer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "AppDefines.h" 3 | #include "LBGameObject.h" 4 | #include "LBGameServer.h" 5 | 6 | class CPacketEcho : public LBNet::CPacketHeader 7 | { 8 | public: 9 | CPacketEcho() = default; 10 | ~CPacketEcho() = default; 11 | 12 | int mData; 13 | }; 14 | 15 | class CTestObject : public LBNet::CGameObject 16 | { 17 | public: 18 | CTestObject() = default; 19 | ~CTestObject() = default; 20 | 21 | void OnAccept() override; 22 | void OnDisconnect() override; 23 | }; 24 | 25 | class CTestServer : public LBNet::CGameServer 26 | { 27 | public: 28 | CTestServer() = default; 29 | ~CTestServer() override; 30 | 31 | LBNet::ErrCode Initialize() override; 32 | LBNet::ErrCode LazyInitialize() override; 33 | LBNet::ErrCode Close() override; 34 | }; 35 | 36 | -------------------------------------------------------------------------------- /TestServer/TestServer.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {F423E23D-3939-47D5-9910-F68CF018912A} 24 | TestServer 25 | 10.0.17763.0 26 | TestServer 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | $(SolutionDir)Bin\ 75 | $(SolutionDir)Intermediate\$(ProjectName)\ 76 | $(ProjectName)D_$(PlatformTarget) 77 | $(SolutionDir)LBUtility\Src\Inc;$(SolutionDir)LBServer\Src\Inc;$(SolutionDir)LBClient\Src\Inc;$(IncludePath) 78 | C:\boost_1_70_0\stage\lib;$(SolutionDir)Bin;$(LibraryPath) 79 | 80 | 81 | $(SolutionDir)Bin\ 82 | $(SolutionDir)Intermediate\$(ProjectName)\ 83 | $(ProjectName)_$(PlatformTarget) 84 | $(SolutionDir)LBUtility\Src\Inc;$(SolutionDir)LBServer\Src\Inc;$(SolutionDir)LBClient\Src\Inc;$(IncludePath) 85 | C:\boost_1_70_0\stage\lib;$(SolutionDir)Bin;$(LibraryPath) 86 | 87 | 88 | $(SolutionDir)Bin\ 89 | $(SolutionDir)Intermediate\$(ProjectName)\ 90 | $(ProjectName)D_$(PlatformTarget) 91 | $(SolutionDir)LBUtility\Src\Inc;$(SolutionDir)LBServer\Src\Inc;$(SolutionDir)LBClient\Src\Inc;$(IncludePath) 92 | C:\boost_1_70_0\stage\lib;$(SolutionDir)Bin;$(LibraryPath) 93 | 94 | 95 | $(SolutionDir)Bin\ 96 | $(SolutionDir)Intermediate\$(ProjectName)\ 97 | $(ProjectName)_$(PlatformTarget) 98 | $(SolutionDir)LBUtility\Src\Inc;$(SolutionDir)LBServer\Src\Inc;$(SolutionDir)LBClient\Src\Inc;$(IncludePath) 99 | C:\boost_1_70_0\stage\lib;$(SolutionDir)Bin;$(LibraryPath) 100 | 101 | 102 | 103 | Level3 104 | Disabled 105 | true 106 | true 107 | C:\boost_1_70_0; 108 | X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 109 | stdcpp17 110 | Disabled 111 | 112 | 113 | 114 | 115 | Level3 116 | Disabled 117 | true 118 | true 119 | C:\boost_1_70_0; 120 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 121 | stdcpp17 122 | Disabled 123 | 124 | 125 | 126 | 127 | Level3 128 | MaxSpeed 129 | true 130 | true 131 | true 132 | true 133 | C:\boost_1_70_0; 134 | X86;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 135 | stdcpp17 136 | 137 | 138 | true 139 | true 140 | 141 | 142 | 143 | 144 | Level3 145 | MaxSpeed 146 | true 147 | true 148 | true 149 | true 150 | C:\boost_1_70_0; 151 | X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 152 | stdcpp17 153 | 154 | 155 | true 156 | true 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /TestServer/TestServer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 소스 파일 20 | 21 | 22 | 소스 파일 23 | 24 | 25 | 26 | 27 | 헤더 파일 28 | 29 | 30 | 헤더 파일 31 | 32 | 33 | -------------------------------------------------------------------------------- /TestServer/TestServer.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /TestServer/main.cpp: -------------------------------------------------------------------------------- 1 | #include "CTestServer.h" 2 | 3 | int main() 4 | { 5 | std::cout << "Start!" << std::endl; 6 | CTestServer Server; 7 | LBNet::CConfig aConfig; 8 | LBNet::ErrCode aErrCode; 9 | 10 | aConfig.SetSessionCnt(10000); 11 | aConfig.AddAddress(54832); 12 | aConfig.AddAddress(54831); 13 | 14 | Server.SetConfig(&aConfig); 15 | aErrCode = Server.Initialize(); 16 | if (aErrCode != 0) 17 | { 18 | // Error! 19 | return aErrCode; 20 | } 21 | 22 | aErrCode = Server.LazyInitialize(); 23 | if (aErrCode != 0) 24 | { 25 | // Error! 26 | return aErrCode; 27 | } 28 | 29 | aErrCode = Server.Run(); 30 | if (aErrCode != 0) 31 | { 32 | // Error! 33 | return aErrCode; 34 | } 35 | 36 | aErrCode = Server.Close(); 37 | if (aErrCode != 0) 38 | { 39 | // Error! 40 | return aErrCode; 41 | } 42 | 43 | return 0; 44 | } --------------------------------------------------------------------------------