From 454e358882af85e269d247cc007dc31e05adc4cb Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 10:17:33 +0100 Subject: [PATCH 01/14] [General] Use boost for IPC --- .gitmodules | 69 ++++++++++++++++++++++++++++++ deps/boost/assert | 1 + deps/boost/config | 1 + deps/boost/container | 1 + deps/boost/core | 1 + deps/boost/date_time | 1 + deps/boost/detail | 1 + deps/boost/functional | 1 + deps/boost/integer | 1 + deps/boost/interprocess | 1 + deps/boost/intrusive | 1 + deps/boost/iterator | 1 + deps/boost/move | 1 + deps/boost/mpl | 1 + deps/boost/predef | 1 + deps/boost/preprocessor | 1 + deps/boost/smart_ptr | 1 + deps/boost/static_assert | 1 + deps/boost/throw_exception | 1 + deps/boost/tuple | 1 + deps/boost/type_traits | 1 + deps/boost/unordered | 1 + deps/boost/utility | 1 + deps/boost/winapi | 1 + premake5.lua | 27 +++++++++++- src/Components/Modules/IPCPipe.cpp | 29 +++++++++++++ 26 files changed, 147 insertions(+), 1 deletion(-) create mode 160000 deps/boost/assert create mode 160000 deps/boost/config create mode 160000 deps/boost/container create mode 160000 deps/boost/core create mode 160000 deps/boost/date_time create mode 160000 deps/boost/detail create mode 160000 deps/boost/functional create mode 160000 deps/boost/integer create mode 160000 deps/boost/interprocess create mode 160000 deps/boost/intrusive create mode 160000 deps/boost/iterator create mode 160000 deps/boost/move create mode 160000 deps/boost/mpl create mode 160000 deps/boost/predef create mode 160000 deps/boost/preprocessor create mode 160000 deps/boost/smart_ptr create mode 160000 deps/boost/static_assert create mode 160000 deps/boost/throw_exception create mode 160000 deps/boost/tuple create mode 160000 deps/boost/type_traits create mode 160000 deps/boost/unordered create mode 160000 deps/boost/utility create mode 160000 deps/boost/winapi diff --git a/.gitmodules b/.gitmodules index 08ae18e6..80d9dfd4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -35,3 +35,72 @@ path = deps/protobuf url = https://github.com/google/protobuf.git branch = 3.2.x +[submodule "deps/boost/interprocess"] + path = deps/boost/interprocess + url = https://github.com/boostorg/interprocess.git +[submodule "deps/boost/config"] + path = deps/boost/config + url = https://github.com/boostorg/config.git +[submodule "deps/boost/date_time"] + path = deps/boost/date_time + url = https://github.com/boostorg/date_time.git +[submodule "deps/boost/assert"] + path = deps/boost/assert + url = https://github.com/boostorg/assert.git +[submodule "deps/boost/utility"] + path = deps/boost/utility + url = https://github.com/boostorg/utility.git +[submodule "deps/boost/detail"] + path = deps/boost/detail + url = https://github.com/boostorg/detail.git +[submodule "deps/boost/winapi"] + path = deps/boost/winapi + url = https://github.com/boostorg/winapi.git +[submodule "deps/boost/integer"] + path = deps/boost/integer + url = https://github.com/boostorg/integer.git +[submodule "deps/boost/move"] + path = deps/boost/move + url = https://github.com/boostorg/move.git +[submodule "deps/boost/static_assert"] + path = deps/boost/static_assert + url = https://github.com/boostorg/static_assert.git +[submodule "deps/boost/container"] + path = deps/boost/container + url = https://github.com/boostorg/container.git +[submodule "deps/boost/intrusive"] + path = deps/boost/intrusive + url = https://github.com/boostorg/intrusive.git +[submodule "deps/boost/core"] + path = deps/boost/core + url = https://github.com/boostorg/core.git +[submodule "deps/boost/functional"] + path = deps/boost/functional + url = https://github.com/boostorg/functional.git +[submodule "deps/boost/type_traits"] + path = deps/boost/type_traits + url = https://github.com/boostorg/type_traits.git +[submodule "deps/boost/preprocessor"] + path = deps/boost/preprocessor + url = https://github.com/boostorg/preprocessor.git +[submodule "deps/boost/smart_ptr"] + path = deps/boost/smart_ptr + url = https://github.com/boostorg/smart_ptr.git +[submodule "deps/boost/throw_exception"] + path = deps/boost/throw_exception + url = https://github.com/boostorg/throw_exception.git +[submodule "deps/boost/predef"] + path = deps/boost/predef + url = https://github.com/boostorg/predef.git +[submodule "deps/boost/mpl"] + path = deps/boost/mpl + url = https://github.com/boostorg/mpl.git +[submodule "deps/boost/unordered"] + path = deps/boost/unordered + url = https://github.com/boostorg/unordered.git +[submodule "deps/boost/iterator"] + path = deps/boost/iterator + url = https://github.com/boostorg/iterator.git +[submodule "deps/boost/tuple"] + path = deps/boost/tuple + url = https://github.com/boostorg/tuple.git diff --git a/deps/boost/assert b/deps/boost/assert new file mode 160000 index 00000000..89e5b86c --- /dev/null +++ b/deps/boost/assert @@ -0,0 +1 @@ +Subproject commit 89e5b86c469c993ea4c53ebc7ed4a9b133f785a6 diff --git a/deps/boost/config b/deps/boost/config new file mode 160000 index 00000000..b4628d91 --- /dev/null +++ b/deps/boost/config @@ -0,0 +1 @@ +Subproject commit b4628d91eb8b2cbf96e3dadee3d6bff97b50ae46 diff --git a/deps/boost/container b/deps/boost/container new file mode 160000 index 00000000..23e9e8b4 --- /dev/null +++ b/deps/boost/container @@ -0,0 +1 @@ +Subproject commit 23e9e8b4946f8b026ced6b048d7a62b4ca81b722 diff --git a/deps/boost/core b/deps/boost/core new file mode 160000 index 00000000..1abd6810 --- /dev/null +++ b/deps/boost/core @@ -0,0 +1 @@ +Subproject commit 1abd68102d26d87109b5eda8d80f8bb0382ce4df diff --git a/deps/boost/date_time b/deps/boost/date_time new file mode 160000 index 00000000..47cf10d5 --- /dev/null +++ b/deps/boost/date_time @@ -0,0 +1 @@ +Subproject commit 47cf10d5fd7cee50d4e53a6132c69a7e1cbb2d0b diff --git a/deps/boost/detail b/deps/boost/detail new file mode 160000 index 00000000..6c111975 --- /dev/null +++ b/deps/boost/detail @@ -0,0 +1 @@ +Subproject commit 6c111975865d112c11101ef8221695cc4cd57562 diff --git a/deps/boost/functional b/deps/boost/functional new file mode 160000 index 00000000..c592e854 --- /dev/null +++ b/deps/boost/functional @@ -0,0 +1 @@ +Subproject commit c592e854919730597b1793f85667e7d88f000d29 diff --git a/deps/boost/integer b/deps/boost/integer new file mode 160000 index 00000000..13b153c6 --- /dev/null +++ b/deps/boost/integer @@ -0,0 +1 @@ +Subproject commit 13b153c657697129cabe7ac8b3e62ef844a62945 diff --git a/deps/boost/interprocess b/deps/boost/interprocess new file mode 160000 index 00000000..0cd4548b --- /dev/null +++ b/deps/boost/interprocess @@ -0,0 +1 @@ +Subproject commit 0cd4548b45a9b9fdac2c58f2acb793095754f821 diff --git a/deps/boost/intrusive b/deps/boost/intrusive new file mode 160000 index 00000000..286f5976 --- /dev/null +++ b/deps/boost/intrusive @@ -0,0 +1 @@ +Subproject commit 286f597606de0d139e256af8c2695d90535be905 diff --git a/deps/boost/iterator b/deps/boost/iterator new file mode 160000 index 00000000..760da84f --- /dev/null +++ b/deps/boost/iterator @@ -0,0 +1 @@ +Subproject commit 760da84f9cbbe87afb7ef845ef5fa6be158637b7 diff --git a/deps/boost/move b/deps/boost/move new file mode 160000 index 00000000..135e598b --- /dev/null +++ b/deps/boost/move @@ -0,0 +1 @@ +Subproject commit 135e598bc4ffc63001d84f93764fddee234f1da2 diff --git a/deps/boost/mpl b/deps/boost/mpl new file mode 160000 index 00000000..3b126bdf --- /dev/null +++ b/deps/boost/mpl @@ -0,0 +1 @@ +Subproject commit 3b126bdf8c7abbfef27101232a379c8e0c3db1ac diff --git a/deps/boost/predef b/deps/boost/predef new file mode 160000 index 00000000..822d09f1 --- /dev/null +++ b/deps/boost/predef @@ -0,0 +1 @@ +Subproject commit 822d09f19bc2f4ea6f42da8e0be83d10ce912ce1 diff --git a/deps/boost/preprocessor b/deps/boost/preprocessor new file mode 160000 index 00000000..d8389ffd --- /dev/null +++ b/deps/boost/preprocessor @@ -0,0 +1 @@ +Subproject commit d8389ffda600ce73d62b077616987744f5f83453 diff --git a/deps/boost/smart_ptr b/deps/boost/smart_ptr new file mode 160000 index 00000000..19147212 --- /dev/null +++ b/deps/boost/smart_ptr @@ -0,0 +1 @@ +Subproject commit 19147212a9edd1facdc9a17cf586b79c92f4116a diff --git a/deps/boost/static_assert b/deps/boost/static_assert new file mode 160000 index 00000000..c2f58a18 --- /dev/null +++ b/deps/boost/static_assert @@ -0,0 +1 @@ +Subproject commit c2f58a187a67502a20aaa14c88625f12e400c5c1 diff --git a/deps/boost/throw_exception b/deps/boost/throw_exception new file mode 160000 index 00000000..f94638e5 --- /dev/null +++ b/deps/boost/throw_exception @@ -0,0 +1 @@ +Subproject commit f94638e5225afff877347576ff7b4170971e7a2a diff --git a/deps/boost/tuple b/deps/boost/tuple new file mode 160000 index 00000000..895af7c9 --- /dev/null +++ b/deps/boost/tuple @@ -0,0 +1 @@ +Subproject commit 895af7c97a2f74980eb459badf67787c2a3ecadf diff --git a/deps/boost/type_traits b/deps/boost/type_traits new file mode 160000 index 00000000..4fffc763 --- /dev/null +++ b/deps/boost/type_traits @@ -0,0 +1 @@ +Subproject commit 4fffc7637da8479e3f94674ef1dd0fc996a7d027 diff --git a/deps/boost/unordered b/deps/boost/unordered new file mode 160000 index 00000000..57cc6d4b --- /dev/null +++ b/deps/boost/unordered @@ -0,0 +1 @@ +Subproject commit 57cc6d4bac1cc93fb8fb05696116b184f3d1fecc diff --git a/deps/boost/utility b/deps/boost/utility new file mode 160000 index 00000000..ccfd741c --- /dev/null +++ b/deps/boost/utility @@ -0,0 +1 @@ +Subproject commit ccfd741c0a423e6c8dc4493e3a4e042b5a34a329 diff --git a/deps/boost/winapi b/deps/boost/winapi new file mode 160000 index 00000000..b017fd88 --- /dev/null +++ b/deps/boost/winapi @@ -0,0 +1 @@ +Subproject commit b017fd886612a9001dfdffeb1aa4663b6e2acda8 diff --git a/premake5.lua b/premake5.lua index d57a9184..d23808ba 100644 --- a/premake5.lua +++ b/premake5.lua @@ -304,7 +304,32 @@ workspace "iw4x" } includedirs { "%{prj.location}/src", - "./src" + "./src", + + -- boost includes + "./deps/boost/mpl/include", + "./deps/boost/core/include", + "./deps/boost/move/include", + "./deps/boost/assert/include", + "./deps/boost/predef/include", + "./deps/boost/config/include", + "./deps/boost/detail/include", + "./deps/boost/winapi/include", + "./deps/boost/integer/include", + "./deps/boost/tuple/include", + "./deps/boost/iterator/include", + "./deps/boost/utility/include", + "./deps/boost/container/include", + "./deps/boost/unordered/include", + "./deps/boost/date_time/include", + "./deps/boost/type_traits/include", + "./deps/boost/preprocessor/include", + "./deps/boost/smart_ptr/include", + "./deps/boost/throw_exception/include", + "./deps/boost/functional/include", + "./deps/boost/intrusive/include", + "./deps/boost/interprocess/include", + "./deps/boost/static_assert/include", } resincludedirs { "$(ProjectDir)src" -- fix for VS IDE diff --git a/src/Components/Modules/IPCPipe.cpp b/src/Components/Modules/IPCPipe.cpp index bc664de4..502dc30c 100644 --- a/src/Components/Modules/IPCPipe.cpp +++ b/src/Components/Modules/IPCPipe.cpp @@ -1,5 +1,21 @@ #include "STDInclude.hpp" +namespace boost +{ + typedef unsigned long long ulong_long_type; +} + +#pragma warning(push) +#pragma warning(disable: 4091) + +#undef sleep +//#define BOOST_DISABLE_WIN32 +#define BOOST_USE_WINDOWS_H +#define BOOST_DATE_TIME_NO_LIB +#include + +#pragma warning(pop) + namespace Components { Pipe IPCPipe::ServerPipe; @@ -242,4 +258,17 @@ namespace Components IPCPipe::ServerPipe.destroy(); IPCPipe::ClientPipe.destroy(); } + + void test() + { + boost::interprocess::message_queue::remove("message_queue"); + + //Create a message_queue. + boost::interprocess::message_queue mq + (boost::interprocess::create_only //only create + , "message_queue" //name + , 100 //max message number + , sizeof(int) //max message size + ); + } } From d05cdcb9ea9c689f1106f54429bc8711f91bfc64 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 10:51:53 +0100 Subject: [PATCH 02/14] [IPCPipe] Example using boost message queues --- src/Components/Modules/IPCPipe.cpp | 46 +++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/Components/Modules/IPCPipe.cpp b/src/Components/Modules/IPCPipe.cpp index 502dc30c..b50eab0a 100644 --- a/src/Components/Modules/IPCPipe.cpp +++ b/src/Components/Modules/IPCPipe.cpp @@ -7,6 +7,7 @@ namespace boost #pragma warning(push) #pragma warning(disable: 4091) +#pragma warning(disable: 4996) #undef sleep //#define BOOST_DISABLE_WIN32 @@ -222,6 +223,38 @@ namespace Components IPCPipe::IPCPipe() { + Command::Add("mq1", [](Command::Params*) + { + boost::interprocess::message_queue::remove("message_queue"); + + //Create a message_queue. + boost::interprocess::message_queue mq(boost::interprocess::create_only, "message_queue", 100, sizeof(int)); + + int i = 1; + mq.send(&i, sizeof(i), 0); + }); + + Command::Add("mq2", [](Command::Params*) + { + boost::interprocess::message_queue mq(boost::interprocess::open_only, "message_queue"); + + unsigned int priority; + boost::interprocess::message_queue::size_type recvd_size; + + //Receive 100 numbers + for (int i = 0; i < 3; ++i) { + int number; + if (!mq.try_receive(&number, sizeof(number), recvd_size, priority) || recvd_size != sizeof(number)) + { + Logger::Print("Nothing received\n"); + } + else + { + Logger::Print("Rec: %d\n", number); + } + } + }); + if (Dedicated::IsEnabled()) return; // Server pipe @@ -258,17 +291,4 @@ namespace Components IPCPipe::ServerPipe.destroy(); IPCPipe::ClientPipe.destroy(); } - - void test() - { - boost::interprocess::message_queue::remove("message_queue"); - - //Create a message_queue. - boost::interprocess::message_queue mq - (boost::interprocess::create_only //only create - , "message_queue" //name - , 100 //max message number - , sizeof(int) //max message size - ); - } } From 1659b9b003a5d787327c1e81e0881aae029b4bc4 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 11:07:48 +0100 Subject: [PATCH 03/14] [Submodules] Use develop branch for boost modules --- .gitmodules | 69 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/.gitmodules b/.gitmodules index 80d9dfd4..e835a944 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,70 +37,93 @@ branch = 3.2.x [submodule "deps/boost/interprocess"] path = deps/boost/interprocess - url = https://github.com/boostorg/interprocess.git + url = https://github.com/boostorg/interprocess.git + branch = develop [submodule "deps/boost/config"] path = deps/boost/config - url = https://github.com/boostorg/config.git + url = https://github.com/boostorg/config.git + branch = develop [submodule "deps/boost/date_time"] path = deps/boost/date_time - url = https://github.com/boostorg/date_time.git + url = https://github.com/boostorg/date_time.git + branch = develop [submodule "deps/boost/assert"] path = deps/boost/assert - url = https://github.com/boostorg/assert.git + url = https://github.com/boostorg/assert.git + branch = develop [submodule "deps/boost/utility"] path = deps/boost/utility - url = https://github.com/boostorg/utility.git + url = https://github.com/boostorg/utility.git + branch = develop [submodule "deps/boost/detail"] path = deps/boost/detail - url = https://github.com/boostorg/detail.git + url = https://github.com/boostorg/detail.git + branch = develop [submodule "deps/boost/winapi"] path = deps/boost/winapi - url = https://github.com/boostorg/winapi.git + url = https://github.com/boostorg/winapi.git + branch = develop [submodule "deps/boost/integer"] path = deps/boost/integer - url = https://github.com/boostorg/integer.git + url = https://github.com/boostorg/integer.git + branch = develop [submodule "deps/boost/move"] path = deps/boost/move - url = https://github.com/boostorg/move.git + url = https://github.com/boostorg/move.git + branch = develop [submodule "deps/boost/static_assert"] path = deps/boost/static_assert - url = https://github.com/boostorg/static_assert.git + url = https://github.com/boostorg/static_assert.git + branch = develop [submodule "deps/boost/container"] path = deps/boost/container - url = https://github.com/boostorg/container.git + url = https://github.com/boostorg/container.git + branch = develop [submodule "deps/boost/intrusive"] path = deps/boost/intrusive - url = https://github.com/boostorg/intrusive.git + url = https://github.com/boostorg/intrusive.git + branch = develop [submodule "deps/boost/core"] path = deps/boost/core - url = https://github.com/boostorg/core.git + url = https://github.com/boostorg/core.git + branch = develop [submodule "deps/boost/functional"] path = deps/boost/functional - url = https://github.com/boostorg/functional.git + url = https://github.com/boostorg/functional.git + branch = develop [submodule "deps/boost/type_traits"] path = deps/boost/type_traits - url = https://github.com/boostorg/type_traits.git + url = https://github.com/boostorg/type_traits.git + branch = develop [submodule "deps/boost/preprocessor"] path = deps/boost/preprocessor - url = https://github.com/boostorg/preprocessor.git + url = https://github.com/boostorg/preprocessor.git + branch = develop [submodule "deps/boost/smart_ptr"] path = deps/boost/smart_ptr - url = https://github.com/boostorg/smart_ptr.git + url = https://github.com/boostorg/smart_ptr.git + branch = develop [submodule "deps/boost/throw_exception"] path = deps/boost/throw_exception - url = https://github.com/boostorg/throw_exception.git + url = https://github.com/boostorg/throw_exception.git + branch = develop [submodule "deps/boost/predef"] path = deps/boost/predef - url = https://github.com/boostorg/predef.git + url = https://github.com/boostorg/predef.git + branch = develop [submodule "deps/boost/mpl"] path = deps/boost/mpl - url = https://github.com/boostorg/mpl.git + url = https://github.com/boostorg/mpl.git + branch = develop [submodule "deps/boost/unordered"] path = deps/boost/unordered - url = https://github.com/boostorg/unordered.git + url = https://github.com/boostorg/unordered.git + branch = develop [submodule "deps/boost/iterator"] path = deps/boost/iterator - url = https://github.com/boostorg/iterator.git + url = https://github.com/boostorg/iterator.git + branch = develop [submodule "deps/boost/tuple"] path = deps/boost/tuple - url = https://github.com/boostorg/tuple.git + url = https://github.com/boostorg/tuple.git + branch = develop From 0ad65d04f35a76a445a71fc6d968f7254e226091 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 11:08:42 +0100 Subject: [PATCH 04/14] [Submodules] Update protobuf --- deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/protobuf b/deps/protobuf index d1f0939a..2c8346a2 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit d1f0939a42ae8a6b6bca95a4b9048d7416e72865 +Subproject commit 2c8346a259791ccb176da80e31e59f1df479bd6d From b0d863e28d975f65dca1bd720889070f125d13fb Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 12:05:58 +0100 Subject: [PATCH 05/14] [Worker] Basic worker project --- premake/boost.lua | 83 +++++++++++++++++++++++++ premake5.lua | 127 ++++++++++++++++++++++++++++++-------- src/Worker/Main.cpp | 15 +++++ src/Worker/Resource.rc | 99 +++++++++++++++++++++++++++++ src/Worker/STDInclude.cpp | 77 +++++++++++++++++++++++ src/Worker/STDInclude.hpp | 125 +++++++++++++++++++++++++++++++++++++ 6 files changed, 501 insertions(+), 25 deletions(-) create mode 100644 premake/boost.lua create mode 100644 src/Worker/Main.cpp create mode 100644 src/Worker/Resource.rc create mode 100644 src/Worker/STDInclude.cpp create mode 100644 src/Worker/STDInclude.hpp diff --git a/premake/boost.lua b/premake/boost.lua new file mode 100644 index 00000000..c880e524 --- /dev/null +++ b/premake/boost.lua @@ -0,0 +1,83 @@ +boost = { + settings = nil, +} + +function boost.setup(settings) + if not settings.source then error("Missing source.") end + + boost.settings = settings +end + +function boost.import() + if not boost.settings then error("Run boost.setup first") end + + --links { "boost" } + boost.includes() +end + +function boost.includes() + if not boost.settings then error("Run boost.setup first") end + + submodules = { + "mpl", + "core", + "move", + "tuple", + "assert", + "predef", + "config", + "detail", + "winapi", + "integer", + "utility", + "iterator", + "container", + "unordered", + "date_time", + "smart_ptr", + "intrusive", + "functional", + "type_traits", + "interprocess", + "preprocessor", + "static_assert", + "throw_exception", + } + + for i, submodule in ipairs(submodules) do + includedirs { path.join(boost.settings.source, string.format("%s/include", submodule)) } + end + + includedirs { boost.settings.source } +end + +function boost.project() + if not boost.settings then error("Run boost.setup first") end + +--[[ + project "boost" + language "C++" + + includedirs + { + boost.settings.source, + } + + files + { + path.join(boost.settings.source, "*.cpp"), + path.join(boost.settings.source, "*.hpp"), + } + removefiles + { + path.join(boost.settings.source, "test*"), + } + + -- not our code, ignore POSIX usage warnings for now + warnings "Off" + + defines { "_LIB" } + removedefines { "_USRDLL", "_DLL" } + kind "StaticLib" +]] +end diff --git a/premake5.lua b/premake5.lua index d23808ba..0f8e7346 100644 --- a/premake5.lua +++ b/premake5.lua @@ -204,6 +204,7 @@ require "premake/pdcurses" require "premake/protobuf" require "premake/sqlite3" require "premake/zlib" +require "premake/boost" base128.setup { @@ -260,6 +261,10 @@ zlib.setup }, source = path.join(depsBasePath, "zlib"), } +boost.setup +{ + source = path.join(depsBasePath, "boost"), +} workspace "iw4x" location "./build" @@ -302,34 +307,12 @@ workspace "iw4x" "./src/**.cpp", --"./src/**.proto", } + removefiles { + "./src/Worker/**.*", + } includedirs { "%{prj.location}/src", "./src", - - -- boost includes - "./deps/boost/mpl/include", - "./deps/boost/core/include", - "./deps/boost/move/include", - "./deps/boost/assert/include", - "./deps/boost/predef/include", - "./deps/boost/config/include", - "./deps/boost/detail/include", - "./deps/boost/winapi/include", - "./deps/boost/integer/include", - "./deps/boost/tuple/include", - "./deps/boost/iterator/include", - "./deps/boost/utility/include", - "./deps/boost/container/include", - "./deps/boost/unordered/include", - "./deps/boost/date_time/include", - "./deps/boost/type_traits/include", - "./deps/boost/preprocessor/include", - "./deps/boost/smart_ptr/include", - "./deps/boost/throw_exception/include", - "./deps/boost/functional/include", - "./deps/boost/intrusive/include", - "./deps/boost/interprocess/include", - "./deps/boost/static_assert/include", } resincludedirs { "$(ProjectDir)src" -- fix for VS IDE @@ -394,6 +377,7 @@ workspace "iw4x" pdcurses.import() protobuf.import() zlib.import() + boost.import() -- fix vpaths for protobuf sources vpaths @@ -494,6 +478,98 @@ workspace "iw4x" } filter {} ]] + +project "iw4xworker" + kind "WindowedApp" + language "C++" + flags { "C++14" } + files { + "./src/Worker/**.rc", + "./src/Worker/**.hpp", + "./src/Worker/**.cpp", + --"./src/**.proto", + } + includedirs { + "%{prj.location}/src", + --"./src", + "./src/Worker", + } + resincludedirs { + "$(ProjectDir)src/Worker" -- fix for VS IDE + } + + -- Pre-compiled header + pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives + pchsource "src/Worker/STDInclude.cpp" -- real path + buildoptions { "/Zm200" } + + protobuf.import() + zlib.import() + boost.import() + + -- fix vpaths for protobuf sources + vpaths + { + ["*"] = { "./src/Worker/**" }, + --["Proto/Generated"] = { "**.pb.*" }, -- meh. + } + + -- Virtual paths + if not _OPTIONS["no-new-structure"] then + vpaths + { + ["Headers/*"] = { "./src/Worker/**.hpp" }, + ["Sources/*"] = { "./src/Worker/**.cpp" }, + ["Resource/*"] = { "./src/Worker/**.rc" }, + } + end + + vpaths + { + ["Docs/*"] = { "**.txt","**.md" }, + } + + -- Pre-build + prebuildcommands + { + "cd %{_MAIN_SCRIPT_DIR}", + "tools\\premake5 generate-buildinfo", + } + + -- Post-build + if _OPTIONS["copy-to"] then + saneCopyToPath = string.gsub(_OPTIONS["copy-to"] .. "\\", "\\\\", "\\") + postbuildcommands { + "if not exist \"" .. saneCopyToPath .. "\" mkdir \"" .. saneCopyToPath .. "\"", + } + + if _OPTIONS["copy-pdb"] then + postbuildcommands { + "copy /y \"$(TargetDir)*.pdb\" \"" .. saneCopyToPath .. "\"", + } + end + + -- This has to be the last one, as otherwise VisualStudio will succeed building even if copying fails + postbuildcommands { + "copy /y \"$(TargetDir)*.dll\" \"" .. saneCopyToPath .. "\"", + } + end + + -- Specific configurations + flags { "UndefinedIdentifiers", "ExtraWarnings" } + + if symbols ~= nil then + symbols "On" + else + flags { "Symbols" } + end + + configuration "Release*" + flags { + "FatalCompileWarnings", + "FatalLinkWarnings", + } + configuration {} group "External dependencies" if not _OPTIONS["disable-bitmessage"] then @@ -511,6 +587,7 @@ workspace "iw4x" pdcurses.project() protobuf.project() zlib.project() + boost.project() rule "ProtobufCompiler" display "Protobuf compiler" diff --git a/src/Worker/Main.cpp b/src/Worker/Main.cpp new file mode 100644 index 00000000..9d7d5101 --- /dev/null +++ b/src/Worker/Main.cpp @@ -0,0 +1,15 @@ +#include "STDInclude.hpp" +#include + +int main(int /*argc*/, char /*argv*/[]) +{ + AllocConsole(); + AttachConsole(GetCurrentProcessId()); + freopen("CONOUT$", "w", stdout); + + printf("Hi"); + _getch(); + + + return 0; +} diff --git a/src/Worker/Resource.rc b/src/Worker/Resource.rc new file mode 100644 index 00000000..1a74c1b4 --- /dev/null +++ b/src/Worker/Resource.rc @@ -0,0 +1,99 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) + +#include "STDInclude.hpp" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_RC + PRODUCTVERSION VERSION_RC + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "IW4x" +#ifdef _DEBUG + VALUE "FileDescription", "IW4 client modification (DEBUG)" +#else + VALUE "FileDescription", "IW4 client modification" +#endif + VALUE "FileVersion", SHORTVERSION + VALUE "InternalName", "iw4x" + VALUE "LegalCopyright", "No rights reserved." + VALUE "OriginalFilename", "iw4x.dll" + VALUE "ProductName", "IW4x" + VALUE "ProductVersion", SHORTVERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/Worker/STDInclude.cpp b/src/Worker/STDInclude.cpp new file mode 100644 index 00000000..2edc9db6 --- /dev/null +++ b/src/Worker/STDInclude.cpp @@ -0,0 +1,77 @@ +#include "STDInclude.hpp" + +// Rename sections +#ifndef DEBUG +#pragma comment(linker, "/merge:.text=.UPX0") +#pragma comment(linker, "/merge:.data=.UPX1") +#pragma comment(linker, "/merge:.rdata=.UPX2") +#pragma comment(linker, "/merge:.tls=.UPX3") +#pragma comment(linker, "/merge:.gfids=.UPX4") +#endif + +#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + +// Do necessary assertions here +// Some compilers treat them differently which causes a size mismatch + +// WinAPI types +AssertSize(DWORD, 4); +AssertSize(WORD, 2); +AssertSize(BYTE, 1); + +// 128 bit integers (only x64) +//AssertSize(__int128, 16); +//AssertSize(unsigned __int128, 16); + +// 64 bit integers +AssertSize(__int64, 8); +AssertSize(unsigned __int64, 8); +AssertSize(long long, 8); +AssertSize(unsigned long long, 8); +AssertSize(int64_t, 8); +AssertSize(uint64_t, 8); +AssertSize(std::int64_t, 8); +AssertSize(std::uint64_t, 8); + +// 32 bit integers +AssertSize(__int32, 4); +AssertSize(unsigned __int32, 4); +AssertSize(int, 4); +AssertSize(unsigned int, 4); +AssertSize(int32_t, 4); +AssertSize(uint32_t, 4); +AssertSize(std::int32_t, 4); +AssertSize(std::uint32_t, 4); + +// 16 bit integers +AssertSize(__int16, 2); +AssertSize(unsigned __int16, 2); +AssertSize(short, 2); +AssertSize(unsigned short, 2); +AssertSize(int16_t, 2); +AssertSize(uint16_t, 2); +AssertSize(std::int16_t, 2); +AssertSize(std::uint16_t, 2); + +// 8 bit integers +AssertSize(bool, 1); +AssertSize(__int8, 1); +AssertSize(unsigned __int8, 1); +AssertSize(char, 1); +AssertSize(unsigned char, 1); +AssertSize(int8_t, 1); +AssertSize(uint8_t, 1); +AssertSize(std::int8_t, 1); +AssertSize(std::uint8_t, 1); + +// Ensure pointers are 4 bytes in size (32-bit) +static_assert(sizeof(intptr_t) == 4 && sizeof(void*) == 4 && sizeof(size_t) == 4, "This doesn't seem to be a 32-bit environment!"); + +extern "C" +{ + // Disable telemetry data logging + void __cdecl __vcrt_initialize_telemetry_provider() {} + void __cdecl __telemetry_main_invoke_trigger() {} + void __cdecl __telemetry_main_return_trigger() {} + void __cdecl __vcrt_uninitialize_telemetry_provider() {} +}; diff --git a/src/Worker/STDInclude.hpp b/src/Worker/STDInclude.hpp new file mode 100644 index 00000000..815900de --- /dev/null +++ b/src/Worker/STDInclude.hpp @@ -0,0 +1,125 @@ +#pragma once + +// Version number +#include "version.h" + +#ifndef RC_INVOKED + +#define VC_EXTRALEAN +#define WIN32_LEAN_AND_MEAN + +// Requires Visual Leak Detector plugin: http://vld.codeplex.com/ +//#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Experimental C++17 features +#include + +// Usefull for debugging +template class Sizer { }; +#define BindNum(x, y) Sizer y; +#define SizeOf(x, y) BindNum(sizeof(x), y) +#define OffsetOf(x, y, z) BindNum(offsetof(x, y), z) + +// Submodules +// Ignore the warnings, it's no our code! +#pragma warning(push) +#pragma warning(disable: 4005) +#pragma warning(disable: 4100) +#pragma warning(disable: 4389) +#pragma warning(disable: 4702) +#pragma warning(disable: 4996) // _CRT_SECURE_NO_WARNINGS +#pragma warning(disable: 6001) +#pragma warning(disable: 6011) +#pragma warning(disable: 6031) +#pragma warning(disable: 6255) +#pragma warning(disable: 6258) +#pragma warning(disable: 6386) +#pragma warning(disable: 6387) + +#include + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +// Protobuf +#include "proto/network.pb.h" +#include "proto/party.pb.h" +#include "proto/auth.pb.h" +#include "proto/node.pb.h" +#include "proto/rcon.pb.h" + +#pragma warning(pop) +/* +#include "Utils/IO.hpp" +#include "Utils/CSV.hpp" +#include "Utils/Time.hpp" +#include "Utils/Cache.hpp" +#include "Utils/Chain.hpp" +#include "Utils/Utils.hpp" +#include "Utils/WebIO.hpp" +#include "Utils/Memory.hpp" +#include "Utils/String.hpp" +#include "Utils/Hooking.hpp" +#include "Utils/Library.hpp" +#include "Utils/InfoString.hpp" +#include "Utils/Compression.hpp" +#include "Utils/Cryptography.hpp" +*/ +// Libraries +#pragma comment(lib, "Winmm.lib") +#pragma comment(lib, "Crypt32.lib") +#pragma comment(lib, "Ws2_32.lib") +#pragma comment(lib, "d3d9.lib") +#pragma comment(lib, "Wininet.lib") +#pragma comment(lib, "shlwapi.lib") +#pragma comment(lib, "Urlmon.lib") +#pragma comment(lib, "Advapi32.lib") +#pragma comment(lib, "rpcrt4.lib") + +// Enable additional literals +using namespace std::literals; + +#endif + +#define STRINGIZE_(x) #x +#define STRINGIZE(x) STRINGIZE_(x) + +#define AssertSize(x, size) static_assert(sizeof(x) == size, STRINGIZE(x) " structure has an invalid size.") +#define AssertOffset(x, y, offset) static_assert(offsetof(x, y) == offset, STRINGIZE(x) "::" STRINGIZE(y) " is not at the right offset.") + +// Resource stuff +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +// Defines below make accessing the resources from the code easier. +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif + +// Enables custom map code +#ifdef DEBUG +#define ENABLE_EXPERIMENTAL_MAP_CODE +#endif From c15aac546d0e73145287429227c39aa263206466 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 14:43:52 +0100 Subject: [PATCH 06/14] [General] Prepare code for use with multiple projects --- src/Components/Modules/Console.cpp | 2 +- src/Components/Modules/Maps.cpp | 4 ++-- src/Components/Modules/ModelSurfs.cpp | 2 +- src/Components/Modules/News.cpp | 11 ++--------- src/Components/Modules/PlayerName.cpp | 4 ++-- src/STDInclude.hpp | 5 +++++ src/Utils/Cache.cpp | 2 +- src/Utils/String.cpp | 8 +++++--- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Components/Modules/Console.cpp b/src/Components/Modules/Console.cpp index 713658da..d5bb5f66 100644 --- a/src/Components/Modules/Console.cpp +++ b/src/Components/Modules/Console.cpp @@ -507,7 +507,7 @@ namespace Components { "con_outputWindowColor", { 0.25f, 0.25f, 0.25f, 0.85f } }, }; - for (int i = 0; i < ARRAY_SIZE(patchedColors); ++i) + for (int i = 0; i < ARRAYSIZE(patchedColors); ++i) { if (std::string(name) == patchedColors[i].name) { diff --git a/src/Components/Modules/Maps.cpp b/src/Components/Modules/Maps.cpp index 3c09608b..0cea2fb8 100644 --- a/src/Components/Modules/Maps.cpp +++ b/src/Components/Modules/Maps.cpp @@ -244,7 +244,7 @@ namespace Components Game::newMapArena_t* arena = &ArenaLength::NewArenas[i]; if (arena->mapName == map) { - for (int j = 0; j < ARRAY_SIZE(arena->keys); ++j) + for (int j = 0; j < ARRAYSIZE(arena->keys); ++j) { if (arena->keys[j] == "dependency"s) { @@ -267,7 +267,7 @@ namespace Components Game::newMapArena_t* arena = &ArenaLength::NewArenas[i]; if (arena->mapName == map) { - for (int j = 0; j < ARRAY_SIZE(arena->keys); ++j) + for (int j = 0; j < ARRAYSIZE(arena->keys); ++j) { if (arena->keys[j] == "allieschar"s) { diff --git a/src/Components/Modules/ModelSurfs.cpp b/src/Components/Modules/ModelSurfs.cpp index 3a9839ab..36a8121c 100644 --- a/src/Components/Modules/ModelSurfs.cpp +++ b/src/Components/Modules/ModelSurfs.cpp @@ -77,7 +77,7 @@ namespace Components header.sectionHeader[Game::SECTION_FIXUP].buffer = allocator.allocateArray(header.sectionHeader[Game::SECTION_FIXUP].size); // Load section data - for (int i = 0; i < ARRAY_SIZE(header.sectionHeader); ++i) + for (int i = 0; i < ARRAYSIZE(header.sectionHeader); ++i) { model.seek(header.sectionHeader[i].offset, FS_SEEK_SET); if (!model.read(header.sectionHeader[i].buffer, header.sectionHeader[i].size)) diff --git a/src/Components/Modules/News.cpp b/src/Components/Modules/News.cpp index cd133499..c0ae951a 100644 --- a/src/Components/Modules/News.cpp +++ b/src/Components/Modules/News.cpp @@ -53,15 +53,8 @@ namespace Components CreateProcessA("updater.exe", nullptr, nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo); - if (pInfo.hThread && pInfo.hThread != INVALID_HANDLE_VALUE) - { - CloseHandle(pInfo.hThread); - } - - if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) - { - CloseHandle(pInfo.hProcess); - } + if (pInfo.hThread && pInfo.hThread != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hThread); + if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hProcess); TerminateProcess(GetCurrentProcess(), exitCode); } diff --git a/src/Components/Modules/PlayerName.cpp b/src/Components/Modules/PlayerName.cpp index f3b16edc..5d62e904 100644 --- a/src/Components/Modules/PlayerName.cpp +++ b/src/Components/Modules/PlayerName.cpp @@ -14,7 +14,7 @@ namespace Components { #if(0) // Disabled for now { - for (int i = 0; i < ARRAY_SIZE(PlayerName::PlayerNames); ++i) + for (int i = 0; i < ARRAYSIZE(PlayerName::PlayerNames); ++i) { PlayerName::PlayerNames[i] = "mumu"; } @@ -26,7 +26,7 @@ namespace Components PlayerName::~PlayerName() { - for (int i = 0; i < ARRAY_SIZE(PlayerName::PlayerNames); ++i) + for (int i = 0; i < ARRAYSIZE(PlayerName::PlayerNames); ++i) { PlayerName::PlayerNames[i].clear(); } diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index be7a6293..fb6447fe 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -83,6 +83,11 @@ template class Sizer { }; #pragma warning(pop) +#define ENABLE_BASE64 +#ifndef DISABLE_BASE128 +#define ENABLE_BASE128 +#endif + #include "Utils/IO.hpp" #include "Utils/CSV.hpp" #include "Utils/Time.hpp" diff --git a/src/Utils/Cache.cpp b/src/Utils/Cache.cpp index 48de605e..cefdb0da 100644 --- a/src/Utils/Cache.cpp +++ b/src/Utils/Cache.cpp @@ -29,7 +29,7 @@ namespace Utils if (Cache::ValidUrl.empty()) { - for (int i = 0; i < ARRAY_SIZE(Cache::Urls); i++) + for (int i = 0; i < ARRAYSIZE(Cache::Urls); i++) { std::string result = Utils::WebIO(useragent, Cache::GetUrl(Cache::Urls[i], path)).setTimeout(timeout)->get(); diff --git a/src/Utils/String.cpp b/src/Utils/String.cpp index 8fbfd180..0ce7a9df 100644 --- a/src/Utils/String.cpp +++ b/src/Utils/String.cpp @@ -1,5 +1,5 @@ #include "STDInclude.hpp" -#ifndef DISABLE_BASE128 +#ifdef ENABLE_BASE128 #include "base128.h" #endif @@ -158,7 +158,7 @@ namespace Utils double bytesPerSecond = (1000.0 / milliseconds) * bytes; int i; - for (i = 0; bytesPerSecond > 1000 && i < ARRAY_SIZE(sizes); ++i) // 1024 or 1000? + for (i = 0; bytesPerSecond > 1000 && i < ARRAYSIZE(sizes); ++i) // 1024 or 1000? { bytesPerSecond /= 1000; } @@ -166,6 +166,7 @@ namespace Utils return Utils::String::VA("%.2f %s/s", static_cast(bytesPerSecond), sizes[i]); } +#ifdef ENABLE_BASE64 // Encodes a given string in Base64 std::string EncodeBase64(const char* input, const unsigned long inputSize) { @@ -182,8 +183,9 @@ namespace Utils { return EncodeBase64(input.data(), input.size()); } +#endif -#ifndef DISABLE_BASE128 +#ifdef ENABLE_BASE128 // Encodes a given string in Base128 std::string EncodeBase128(const std::string& input) { From 8764d8327f1e58e488a7780608818096fc935b8d Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 14:44:36 +0100 Subject: [PATCH 07/14] [Premake] Allow using Utils in both projects --- premake5.lua | 32 ++++++++++++++++++++++++++------ src/Worker/STDInclude.hpp | 27 +++++++++++---------------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/premake5.lua b/premake5.lua index 0f8e7346..c14c35d3 100644 --- a/premake5.lua +++ b/premake5.lua @@ -406,8 +406,9 @@ workspace "iw4x" -- Pre-build prebuildcommands { - "cd %{_MAIN_SCRIPT_DIR}", + "pushd %{_MAIN_SCRIPT_DIR}", "tools\\premake5 generate-buildinfo", + "popd", } -- Post-build @@ -480,15 +481,24 @@ workspace "iw4x" ]] project "iw4xworker" - kind "WindowedApp" language "C++" flags { "C++14" } files { "./src/Worker/**.rc", "./src/Worker/**.hpp", "./src/Worker/**.cpp", + "./src/Utils/**.hpp", + "./src/Utils/**.cpp", --"./src/**.proto", } + removefiles { + "./src/Utils/CSV.*", + "./src/Utils/Cache.*", + "./src/Utils/Stream.*", + "./src/Utils/Hooking.*", + "./src/Utils/InfoString.*", + "./src/Utils/Cryptography.*", + } includedirs { "%{prj.location}/src", --"./src", @@ -519,9 +529,16 @@ project "iw4xworker" vpaths { ["Headers/*"] = { "./src/Worker/**.hpp" }, + ["Headers/Utils/*"] = { "./src/Utils/**.hpp" }, ["Sources/*"] = { "./src/Worker/**.cpp" }, + ["Sources/Utils/*"] = { "./src/Utils/**.cpp" }, ["Resource/*"] = { "./src/Worker/**.rc" }, } + else + vpaths + { + ["Utils/*"] = { "./src/Utils/**" }, + } end vpaths @@ -532,26 +549,27 @@ project "iw4xworker" -- Pre-build prebuildcommands { - "cd %{_MAIN_SCRIPT_DIR}", + "pushd %{_MAIN_SCRIPT_DIR}", "tools\\premake5 generate-buildinfo", + "popd", } -- Post-build if _OPTIONS["copy-to"] then saneCopyToPath = string.gsub(_OPTIONS["copy-to"] .. "\\", "\\\\", "\\") postbuildcommands { - "if not exist \"" .. saneCopyToPath .. "\" mkdir \"" .. saneCopyToPath .. "\"", + "if not exist \"" .. saneCopyToPath .. "\" mkdir \"" .. saneCopyToPath .. "iw4x\\\"", } if _OPTIONS["copy-pdb"] then postbuildcommands { - "copy /y \"$(TargetDir)*.pdb\" \"" .. saneCopyToPath .. "\"", + "copy /y \"$(TargetDir)*.pdb\" \"" .. saneCopyToPath .. "iw4x\\\"", } end -- This has to be the last one, as otherwise VisualStudio will succeed building even if copying fails postbuildcommands { - "copy /y \"$(TargetDir)*.dll\" \"" .. saneCopyToPath .. "\"", + "copy /y \"$(TargetDir)*.exe\" \"" .. saneCopyToPath .. "iw4x\\\"", } end @@ -564,7 +582,9 @@ project "iw4xworker" flags { "Symbols" } end + kind "ConsoleApp" configuration "Release*" + kind "WindowedApp" flags { "FatalCompileWarnings", "FatalLinkWarnings", diff --git a/src/Worker/STDInclude.hpp b/src/Worker/STDInclude.hpp index 815900de..12ede63f 100644 --- a/src/Worker/STDInclude.hpp +++ b/src/Worker/STDInclude.hpp @@ -70,22 +70,17 @@ template class Sizer { }; #include "proto/rcon.pb.h" #pragma warning(pop) -/* -#include "Utils/IO.hpp" -#include "Utils/CSV.hpp" -#include "Utils/Time.hpp" -#include "Utils/Cache.hpp" -#include "Utils/Chain.hpp" -#include "Utils/Utils.hpp" -#include "Utils/WebIO.hpp" -#include "Utils/Memory.hpp" -#include "Utils/String.hpp" -#include "Utils/Hooking.hpp" -#include "Utils/Library.hpp" -#include "Utils/InfoString.hpp" -#include "Utils/Compression.hpp" -#include "Utils/Cryptography.hpp" -*/ + +#include "../Utils/IO.hpp" +#include "../Utils/Time.hpp" +#include "../Utils/Chain.hpp" +#include "../Utils/Utils.hpp" +#include "../Utils/WebIO.hpp" +#include "../Utils/Memory.hpp" +#include "../Utils/String.hpp" +#include "../Utils/Library.hpp" +#include "../Utils/Compression.hpp" + // Libraries #pragma comment(lib, "Winmm.lib") #pragma comment(lib, "Crypt32.lib") From ef01b4e617cb99630ecdaa0e18bbc5e9f37fe893 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 15:06:31 +0100 Subject: [PATCH 08/14] [IPCPipe] Launch the worker process --- src/Components/Modules/IPCPipe.cpp | 12 +++++++ src/Worker/Main.cpp | 54 ++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/Components/Modules/IPCPipe.cpp b/src/Components/Modules/IPCPipe.cpp index b50eab0a..3cdd88b9 100644 --- a/src/Components/Modules/IPCPipe.cpp +++ b/src/Components/Modules/IPCPipe.cpp @@ -284,6 +284,18 @@ namespace Components Logger::Print("Sending ping to pipe!\n"); IPCPipe::Write("ping", ""); }); + + STARTUPINFOA sInfo; + PROCESS_INFORMATION pInfo; + + ZeroMemory(&sInfo, sizeof(sInfo)); + ZeroMemory(&pInfo, sizeof(pInfo)); + sInfo.cb = sizeof(sInfo); + + CreateProcessA("iw4x/iw4xworker.exe", const_cast(Utils::String::VA("-parentProc %d", GetCurrentProcessId())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo); + + if (pInfo.hThread && pInfo.hThread != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hThread); + if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hProcess); } void IPCPipe::preDestroy() diff --git a/src/Worker/Main.cpp b/src/Worker/Main.cpp index 9d7d5101..d32947d6 100644 --- a/src/Worker/Main.cpp +++ b/src/Worker/Main.cpp @@ -1,15 +1,57 @@ #include "STDInclude.hpp" #include -int main(int /*argc*/, char /*argv*/[]) +void worker(bool* terminator) { - AllocConsole(); - AttachConsole(GetCurrentProcessId()); - freopen("CONOUT$", "w", stdout); + printf("Worker started\n"); + + while(!*terminator) + { + std::this_thread::sleep_for(1ms); + } + + printf("Terminating worker\n"); +} + +int main() +{ + bool terminator = false; + char* command = "-parentProc "; + char* parentProc = strstr(GetCommandLineA(), command); + + if (!parentProc) + { + printf("No parent process argument found\n"); + return 0; + } + + parentProc += strlen(command); + int pid = atoi(parentProc); + + printf("Attaching to process %d...\n", pid); + + HANDLE processHandle = OpenProcess(SYNCHRONIZE, FALSE, pid); + if (!processHandle || processHandle == INVALID_HANDLE_VALUE) + { + printf("Unable to attach to parent process\n"); + return 0; + } + + printf("Successfully attached to parent process\n"); + printf("Starting worker...\n"); + + std::thread runner(worker, &terminator); + + WaitForSingleObject(processHandle, INFINITE); + CloseHandle(processHandle); + + terminator = true; + + printf("Awaiting worker termination...\n"); + if (runner.joinable()) runner.join(); + printf("Worker terminated\n"); - printf("Hi"); _getch(); - return 0; } From fc0bf1acc1f5d90f7c1b432df907f4b5f9f3e31a Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 17:21:10 +0100 Subject: [PATCH 09/14] [IPC] Basic IPC channel class --- src/Components/Modules/IPCPipe.cpp | 67 +++++-------------- src/STDInclude.hpp | 6 ++ src/Utils/IPC.cpp | 104 +++++++++++++++++++++++++++++ src/Utils/IPC.hpp | 55 +++++++++++++++ src/Worker/Main.cpp | 12 +++- src/Worker/STDInclude.hpp | 6 ++ 6 files changed, 200 insertions(+), 50 deletions(-) create mode 100644 src/Utils/IPC.cpp create mode 100644 src/Utils/IPC.hpp diff --git a/src/Components/Modules/IPCPipe.cpp b/src/Components/Modules/IPCPipe.cpp index 3cdd88b9..640ca0f7 100644 --- a/src/Components/Modules/IPCPipe.cpp +++ b/src/Components/Modules/IPCPipe.cpp @@ -1,22 +1,5 @@ #include "STDInclude.hpp" -namespace boost -{ - typedef unsigned long long ulong_long_type; -} - -#pragma warning(push) -#pragma warning(disable: 4091) -#pragma warning(disable: 4996) - -#undef sleep -//#define BOOST_DISABLE_WIN32 -#define BOOST_USE_WINDOWS_H -#define BOOST_DATE_TIME_NO_LIB -#include - -#pragma warning(pop) - namespace Components { Pipe IPCPipe::ServerPipe; @@ -223,38 +206,6 @@ namespace Components IPCPipe::IPCPipe() { - Command::Add("mq1", [](Command::Params*) - { - boost::interprocess::message_queue::remove("message_queue"); - - //Create a message_queue. - boost::interprocess::message_queue mq(boost::interprocess::create_only, "message_queue", 100, sizeof(int)); - - int i = 1; - mq.send(&i, sizeof(i), 0); - }); - - Command::Add("mq2", [](Command::Params*) - { - boost::interprocess::message_queue mq(boost::interprocess::open_only, "message_queue"); - - unsigned int priority; - boost::interprocess::message_queue::size_type recvd_size; - - //Receive 100 numbers - for (int i = 0; i < 3; ++i) { - int number; - if (!mq.try_receive(&number, sizeof(number), recvd_size, priority) || recvd_size != sizeof(number)) - { - Logger::Print("Nothing received\n"); - } - else - { - Logger::Print("Rec: %d\n", number); - } - } - }); - if (Dedicated::IsEnabled()) return; // Server pipe @@ -285,6 +236,24 @@ namespace Components IPCPipe::Write("ping", ""); }); + static Utils::IPC::Channel channel("iw4xChannel"); + static Utils::IPC::Channel channel2("iw4xChannel2"); + channel.send("Hello world!"); + + Command::Add("ipcchan", [](Command::Params* params) + { + channel.send(params->join(1)); + }); + + QuickPatch::OnFrame([]() + { + std::string buffer; + if(channel2.receive(&buffer)) + { + Logger::Print("Data received: %s\n", buffer.data()); + } + }); + STARTUPINFOA sInfo; PROCESS_INFORMATION pInfo; diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index fb6447fe..2667fb2d 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -18,6 +18,11 @@ #include #include +#pragma warning(push) +#pragma warning(disable: 4996) +#include +#pragma warning(pop) + #include #include #include @@ -89,6 +94,7 @@ template class Sizer { }; #endif #include "Utils/IO.hpp" +#include "Utils/IPC.hpp" #include "Utils/CSV.hpp" #include "Utils/Time.hpp" #include "Utils/Cache.hpp" diff --git a/src/Utils/IPC.cpp b/src/Utils/IPC.cpp new file mode 100644 index 00000000..e763be18 --- /dev/null +++ b/src/Utils/IPC.cpp @@ -0,0 +1,104 @@ +#include "STDInclude.hpp" + +namespace Utils +{ + namespace IPC + { + Channel::Channel(std::string _name, int queueSize, int bufferSize) : name(_name) + { + //boost::interprocess::message_queue::remove(this->name.data()); + queue.reset(new boost::interprocess::message_queue(boost::interprocess::open_or_create, this->name.data(), queueSize, bufferSize + sizeof(Channel::Header))); + } + + Channel::~Channel() + { + boost::interprocess::message_queue::remove(this->name.data()); + } + + bool Channel::receive(std::string* data) + { + if (!data) return false; + data->clear(); + + if(this->packet.size() < this->queue->get_max_msg_size()) + { + packet.resize(this->queue->get_max_msg_size()); + } + + const Channel::Header* header = reinterpret_cast(packet.data()); + const char* buffer = reinterpret_cast(header + 1); + + unsigned int priority; + boost::interprocess::message_queue::size_type recvd_size; + + if (this->queue->try_receive(const_cast(packet.data()), packet.size(), recvd_size, priority)) + { + if ((recvd_size - sizeof(Channel::Header)) != header->fragmentSize || header->fragmentPart) return false; + data->append(buffer, header->fragmentSize); + + if(header->fragmented) + { + Channel::Header mainHeader = *header; + unsigned int part = mainHeader.fragmentPart; + + while (true) + { + this->queue->receive(const_cast(packet.data()), packet.size(), recvd_size, priority); + + if (header->packetId != mainHeader.packetId || header->totalSize != mainHeader.totalSize || header->fragmentPart != (++part)) + { + data->clear(); + return false; + } + + data->append(buffer, header->fragmentSize); + + if(header->totalSize <= data->size()) + { + break; + } + } + } + + return true; + } + + return false; + } + + void Channel::send(std::string data) + { + const size_t fragmentSize = (this->queue->get_max_msg_size() - sizeof(Channel::Header)) - 1; + + Channel::Header header; + header.fragmented = (data.size() + sizeof(Channel::Header)) > this->queue->get_max_msg_size(); + header.packetId = static_cast(timeGetTime() + rand());; + header.totalSize = data.size(); + + size_t sentSize = 0; + for (unsigned short i = 0; sentSize < data.size(); ++i) + { + header.fragmentPart = i; + header.fragmentSize = std::min(fragmentSize, data.size() - (fragmentSize * i)); + + std::string buffer; + buffer.append(reinterpret_cast(&header), sizeof(Channel::Header)); + buffer.append(data.data() + sentSize, header.fragmentSize); + Channel::sendMessage(buffer); + + sentSize += header.fragmentSize; + } + } + + void Channel::sendMessage(std::string data) + { + if (data.size() <= this->queue->get_max_msg_size()) + { + while (!this->queue->try_send(data.data(), data.size(), 0)) + { + std::this_thread::sleep_for(100us); + } + } + } + } +} diff --git a/src/Utils/IPC.hpp b/src/Utils/IPC.hpp new file mode 100644 index 00000000..72c72382 --- /dev/null +++ b/src/Utils/IPC.hpp @@ -0,0 +1,55 @@ +#pragma once + +namespace boost +{ + typedef unsigned long long ulong_long_type; +} + +#pragma warning(push) +#pragma warning(disable: 4091) +#pragma warning(disable: 4996) +#define _SCL_SECURE_NO_WARNINGS + +#ifdef sleep +#undef sleep +#endif + +//#define BOOST_DISABLE_WIN32 +#define BOOST_USE_WINDOWS_H +#define BOOST_DATE_TIME_NO_LIB +#include + +#undef _SCL_SECURE_NO_WARNINGS +#pragma warning(pop) + +namespace Utils +{ + namespace IPC + { + class Channel + { + public: + Channel(std::string _name, int queueSize = 100, int bufferSize = 20); + ~Channel(); + + bool receive(std::string* data); + void send(std::string data); + + private: + struct Header + { + bool fragmented; + unsigned short packetId; + size_t fragmentSize; + size_t totalSize; + unsigned int fragmentPart; + }; + + void sendMessage(std::string data); + + std::unique_ptr queue; + std::string packet; + std::string name; + }; + } +} diff --git a/src/Worker/Main.cpp b/src/Worker/Main.cpp index d32947d6..6050ff4f 100644 --- a/src/Worker/Main.cpp +++ b/src/Worker/Main.cpp @@ -4,9 +4,18 @@ void worker(bool* terminator) { printf("Worker started\n"); + Utils::IPC::Channel channel("iw4xChannel"); + Utils::IPC::Channel channel2("iw4xChannel2"); while(!*terminator) { + std::string buffer; + if(channel.receive(&buffer)) + { + printf("Data received: %s\n", buffer.data()); + channel2.send("OK " + buffer); + } + std::this_thread::sleep_for(1ms); } @@ -51,7 +60,8 @@ int main() if (runner.joinable()) runner.join(); printf("Worker terminated\n"); - _getch(); + //_getch(); + google::protobuf::ShutdownProtobufLibrary(); return 0; } diff --git a/src/Worker/STDInclude.hpp b/src/Worker/STDInclude.hpp index 12ede63f..2237256d 100644 --- a/src/Worker/STDInclude.hpp +++ b/src/Worker/STDInclude.hpp @@ -18,6 +18,11 @@ #include #include +#pragma warning(push) +#pragma warning(disable: 4996) +#include +#pragma warning(pop) + #include #include #include @@ -72,6 +77,7 @@ template class Sizer { }; #pragma warning(pop) #include "../Utils/IO.hpp" +#include "../Utils/IPC.hpp" #include "../Utils/Time.hpp" #include "../Utils/Chain.hpp" #include "../Utils/Utils.hpp" From 4e84c297e4a8ad6a82dbb38bd1b1eccc26178914 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 22:03:35 +0100 Subject: [PATCH 10/14] [IPC] Use iw4x as worker process instead of creating a separate binary --- README.md | 1 - premake5.lua | 122 ---------------------------- src/Components/Modules/IPCPipe.cpp | 29 ++++++- src/Main.cpp | 43 ++++++---- src/STDInclude.hpp | 1 + src/Utils/IPC.cpp | 6 +- src/Utils/IPC.hpp | 40 ++++++++- src/Worker/Main.cpp | 67 --------------- src/Worker/Resource.rc | 99 ----------------------- src/Worker/Runner.cpp | 60 ++++++++++++++ src/Worker/Runner.hpp | 19 +++++ src/Worker/STDInclude.cpp | 77 ------------------ src/Worker/STDInclude.hpp | 126 ----------------------------- src/Worker/Worker.cpp | 65 +++++++++++++++ src/Worker/Worker.hpp | 11 +++ 15 files changed, 251 insertions(+), 515 deletions(-) delete mode 100644 src/Worker/Main.cpp delete mode 100644 src/Worker/Resource.rc create mode 100644 src/Worker/Runner.cpp create mode 100644 src/Worker/Runner.hpp delete mode 100644 src/Worker/STDInclude.cpp delete mode 100644 src/Worker/STDInclude.hpp create mode 100644 src/Worker/Worker.cpp create mode 100644 src/Worker/Worker.hpp diff --git a/README.md b/README.md index 1587e2f7..c4c4eee9 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,5 @@ | `--disable-bitmessage` | Disable use of BitMessage completely. | | `--disable-node-log` | Disable debugging messages for Nodes in Debug builds. | | `--disable-base128` | Disable base128 encoding for minidumps. | -| `--disable-steam-game` | Disable Steam's in-game setting. | | `--no-new-structure` | Do not use new virtual path structure (separating headers and source files). | | `--enable-dxsdk` | Enable DirectX SDK (required for GfxMap exporting). | diff --git a/premake5.lua b/premake5.lua index c14c35d3..70f9e661 100644 --- a/premake5.lua +++ b/premake5.lua @@ -88,11 +88,6 @@ newoption { description = "Disable base128 encoding for minidumps." } -newoption { - trigger = "disable-steam-game", - description = "Disable Steam's in-game setting." -} - newoption { trigger = "enable-dxsdk", description = "Enable DirectX SDK (required for GfxMap exporting)." @@ -307,9 +302,6 @@ workspace "iw4x" "./src/**.cpp", --"./src/**.proto", } - removefiles { - "./src/Worker/**.*", - } includedirs { "%{prj.location}/src", "./src", @@ -349,9 +341,6 @@ workspace "iw4x" if _OPTIONS["disable-base128"] then defines { "DISABLE_BASE128" } end - if _OPTIONS["disable-steam-game"] then - defines { "DISABLE_STEAM_GAME" } - end if _OPTIONS["enable-dxsdk"] then defines { "ENABLE_DXSDK" } includedirs { "%DXSDK_DIR%Include" } @@ -479,117 +468,6 @@ workspace "iw4x" } filter {} ]] - -project "iw4xworker" - language "C++" - flags { "C++14" } - files { - "./src/Worker/**.rc", - "./src/Worker/**.hpp", - "./src/Worker/**.cpp", - "./src/Utils/**.hpp", - "./src/Utils/**.cpp", - --"./src/**.proto", - } - removefiles { - "./src/Utils/CSV.*", - "./src/Utils/Cache.*", - "./src/Utils/Stream.*", - "./src/Utils/Hooking.*", - "./src/Utils/InfoString.*", - "./src/Utils/Cryptography.*", - } - includedirs { - "%{prj.location}/src", - --"./src", - "./src/Worker", - } - resincludedirs { - "$(ProjectDir)src/Worker" -- fix for VS IDE - } - - -- Pre-compiled header - pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives - pchsource "src/Worker/STDInclude.cpp" -- real path - buildoptions { "/Zm200" } - - protobuf.import() - zlib.import() - boost.import() - - -- fix vpaths for protobuf sources - vpaths - { - ["*"] = { "./src/Worker/**" }, - --["Proto/Generated"] = { "**.pb.*" }, -- meh. - } - - -- Virtual paths - if not _OPTIONS["no-new-structure"] then - vpaths - { - ["Headers/*"] = { "./src/Worker/**.hpp" }, - ["Headers/Utils/*"] = { "./src/Utils/**.hpp" }, - ["Sources/*"] = { "./src/Worker/**.cpp" }, - ["Sources/Utils/*"] = { "./src/Utils/**.cpp" }, - ["Resource/*"] = { "./src/Worker/**.rc" }, - } - else - vpaths - { - ["Utils/*"] = { "./src/Utils/**" }, - } - end - - vpaths - { - ["Docs/*"] = { "**.txt","**.md" }, - } - - -- Pre-build - prebuildcommands - { - "pushd %{_MAIN_SCRIPT_DIR}", - "tools\\premake5 generate-buildinfo", - "popd", - } - - -- Post-build - if _OPTIONS["copy-to"] then - saneCopyToPath = string.gsub(_OPTIONS["copy-to"] .. "\\", "\\\\", "\\") - postbuildcommands { - "if not exist \"" .. saneCopyToPath .. "\" mkdir \"" .. saneCopyToPath .. "iw4x\\\"", - } - - if _OPTIONS["copy-pdb"] then - postbuildcommands { - "copy /y \"$(TargetDir)*.pdb\" \"" .. saneCopyToPath .. "iw4x\\\"", - } - end - - -- This has to be the last one, as otherwise VisualStudio will succeed building even if copying fails - postbuildcommands { - "copy /y \"$(TargetDir)*.exe\" \"" .. saneCopyToPath .. "iw4x\\\"", - } - end - - -- Specific configurations - flags { "UndefinedIdentifiers", "ExtraWarnings" } - - if symbols ~= nil then - symbols "On" - else - flags { "Symbols" } - end - - kind "ConsoleApp" - configuration "Release*" - kind "WindowedApp" - flags { - "FatalCompileWarnings", - "FatalLinkWarnings", - } - configuration {} group "External dependencies" if not _OPTIONS["disable-bitmessage"] then diff --git a/src/Components/Modules/IPCPipe.cpp b/src/Components/Modules/IPCPipe.cpp index 640ca0f7..1b558082 100644 --- a/src/Components/Modules/IPCPipe.cpp +++ b/src/Components/Modules/IPCPipe.cpp @@ -236,8 +236,7 @@ namespace Components IPCPipe::Write("ping", ""); }); - static Utils::IPC::Channel channel("iw4xChannel"); - static Utils::IPC::Channel channel2("iw4xChannel2"); + static Utils::IPC::BidirectionalChannel channel("iw4xChannel", !Worker::IsWorker()); channel.send("Hello world!"); Command::Add("ipcchan", [](Command::Params* params) @@ -245,10 +244,32 @@ namespace Components channel.send(params->join(1)); }); + Command::Add("ipcchantest", [](Command::Params*) + { + std::string buffer; + buffer.reserve(2048); + + for(int i = 0; i < 1020; ++i) + { + buffer.append("a", 1); + } + + buffer.append("lolsnakerules!"); + + for (int i = 0; i < 1020; ++i) + { + buffer.append("a", 1); + } + + buffer.append("lolsnakerules!"); + + channel.send(buffer); + }); + QuickPatch::OnFrame([]() { std::string buffer; - if(channel2.receive(&buffer)) + if(channel.receive(&buffer)) { Logger::Print("Data received: %s\n", buffer.data()); } @@ -261,7 +282,7 @@ namespace Components ZeroMemory(&pInfo, sizeof(pInfo)); sInfo.cb = sizeof(sInfo); - CreateProcessA("iw4x/iw4xworker.exe", const_cast(Utils::String::VA("-parentProc %d", GetCurrentProcessId())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo); + CreateProcessA("iw4x.exe", const_cast(Utils::String::VA("-parent %d", GetCurrentProcessId())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo); if (pInfo.hThread && pInfo.hThread != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hThread); if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hProcess); diff --git a/src/Main.cpp b/src/Main.cpp index 59728f33..3587fd52 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -20,28 +20,43 @@ namespace Main Main::EntryPointHook.uninstall(); Main::SetEnvironment(); - Utils::Cryptography::Initialize(); - Components::Loader::Initialize(); + + if(Worker::IsWorker()) + { + Worker::Initialize(); + } + else + { + Components::Loader::Initialize(); #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - if (Components::Loader::PerformingUnitTests()) - { - DWORD result = (Components::Loader::PerformUnitTests() ? 0 : -1); - Components::Loader::Uninitialize(); - ExitProcess(result); - } + if (Components::Loader::PerformingUnitTests()) + { + DWORD result = (Components::Loader::PerformUnitTests() ? 0 : -1); + Components::Loader::Uninitialize(); + ExitProcess(result); + } #else - if (Components::Flags::HasFlag("tests")) - { - Components::Logger::Print("Unit tests are disabled outside the debug environment!\n"); - } + if (Components::Flags::HasFlag("tests")) + { + Components::Logger::Print("Unit tests are disabled outside the debug environment!\n"); + } #endif + } } void Uninitialize() { - Components::Loader::Uninitialize(); + if(Worker::IsWorker()) + { + Worker::Uninitialize(); + } + else + { + Components::Loader::Uninitialize(); + } + Utils::Cache::Uninitialize(); google::protobuf::ShutdownProtobufLibrary(); } @@ -51,8 +66,6 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { - Steam::Proxy::RunMod(); - // Ensure we're working with our desired binary if (Utils::Hook::Get(0x4C0FFF) != 0x6824748B) { diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index 2667fb2d..d6cb65ab 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -117,6 +117,7 @@ template class Sizer { }; #include "Utils/Stream.hpp" #include "Components/Loader.hpp" +#include "Worker/Worker.hpp" // Libraries #pragma comment(lib, "Winmm.lib") diff --git a/src/Utils/IPC.cpp b/src/Utils/IPC.cpp index e763be18..79ab2c86 100644 --- a/src/Utils/IPC.cpp +++ b/src/Utils/IPC.cpp @@ -4,9 +4,9 @@ namespace Utils { namespace IPC { - Channel::Channel(std::string _name, int queueSize, int bufferSize) : name(_name) + Channel::Channel(std::string _name, int queueSize, int bufferSize, bool creator) : name(_name) { - //boost::interprocess::message_queue::remove(this->name.data()); + if(creator) boost::interprocess::message_queue::remove(this->name.data()); queue.reset(new boost::interprocess::message_queue(boost::interprocess::open_or_create, this->name.data(), queueSize, bufferSize + sizeof(Channel::Header))); } @@ -43,7 +43,7 @@ namespace Utils while (true) { - this->queue->receive(const_cast(packet.data()), packet.size(), recvd_size, priority); + if (!this->queue->try_receive(const_cast(packet.data()), packet.size(), recvd_size, priority)) return false; if (header->packetId != mainHeader.packetId || header->totalSize != mainHeader.totalSize || header->fragmentPart != (++part)) { diff --git a/src/Utils/IPC.hpp b/src/Utils/IPC.hpp index 72c72382..7d91c9d4 100644 --- a/src/Utils/IPC.hpp +++ b/src/Utils/IPC.hpp @@ -29,7 +29,7 @@ namespace Utils class Channel { public: - Channel(std::string _name, int queueSize = 100, int bufferSize = 20); + Channel(std::string _name, int queueSize = 100, int bufferSize = 1024, bool creator = false); ~Channel(); bool receive(std::string* data); @@ -51,5 +51,43 @@ namespace Utils std::string packet; std::string name; }; + + class BidirectionalChannel + { + public: + BidirectionalChannel(std::string name, bool server, int queueSize = 100, int bufferSize = 1024) : isServer(server), + channel1(name, queueSize, bufferSize, server), + channel2(name + "2", queueSize, bufferSize, server) + {} + + bool receive(std::string* data) + { + if(this->isServer) + { + return channel1.receive(data); + } + else + { + return channel2.receive(data); + } + } + + void send(std::string data) + { + if (this->isServer) + { + return channel2.send(data); + } + else + { + return channel1.send(data); + } + } + + private: + const bool isServer; + Channel channel1; + Channel channel2; + }; } } diff --git a/src/Worker/Main.cpp b/src/Worker/Main.cpp deleted file mode 100644 index 6050ff4f..00000000 --- a/src/Worker/Main.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "STDInclude.hpp" -#include - -void worker(bool* terminator) -{ - printf("Worker started\n"); - Utils::IPC::Channel channel("iw4xChannel"); - Utils::IPC::Channel channel2("iw4xChannel2"); - - while(!*terminator) - { - std::string buffer; - if(channel.receive(&buffer)) - { - printf("Data received: %s\n", buffer.data()); - channel2.send("OK " + buffer); - } - - std::this_thread::sleep_for(1ms); - } - - printf("Terminating worker\n"); -} - -int main() -{ - bool terminator = false; - char* command = "-parentProc "; - char* parentProc = strstr(GetCommandLineA(), command); - - if (!parentProc) - { - printf("No parent process argument found\n"); - return 0; - } - - parentProc += strlen(command); - int pid = atoi(parentProc); - - printf("Attaching to process %d...\n", pid); - - HANDLE processHandle = OpenProcess(SYNCHRONIZE, FALSE, pid); - if (!processHandle || processHandle == INVALID_HANDLE_VALUE) - { - printf("Unable to attach to parent process\n"); - return 0; - } - - printf("Successfully attached to parent process\n"); - printf("Starting worker...\n"); - - std::thread runner(worker, &terminator); - - WaitForSingleObject(processHandle, INFINITE); - CloseHandle(processHandle); - - terminator = true; - - printf("Awaiting worker termination...\n"); - if (runner.joinable()) runner.join(); - printf("Worker terminated\n"); - - //_getch(); - - google::protobuf::ShutdownProtobufLibrary(); - return 0; -} diff --git a/src/Worker/Resource.rc b/src/Worker/Resource.rc deleted file mode 100644 index 1a74c1b4..00000000 --- a/src/Worker/Resource.rc +++ /dev/null @@ -1,99 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) - -#include "STDInclude.hpp" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "windows.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "#include ""windows.h""\r\n" - "\0" -END - -2 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VERSION_RC - PRODUCTVERSION VERSION_RC - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE VFT_DLL - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "IW4x" -#ifdef _DEBUG - VALUE "FileDescription", "IW4 client modification (DEBUG)" -#else - VALUE "FileDescription", "IW4 client modification" -#endif - VALUE "FileVersion", SHORTVERSION - VALUE "InternalName", "iw4x" - VALUE "LegalCopyright", "No rights reserved." - VALUE "OriginalFilename", "iw4x.dll" - VALUE "ProductName", "IW4x" - VALUE "ProductVersion", SHORTVERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/Worker/Runner.cpp b/src/Worker/Runner.cpp new file mode 100644 index 00000000..19e56d93 --- /dev/null +++ b/src/Worker/Runner.cpp @@ -0,0 +1,60 @@ +#include "STDInclude.hpp" + +namespace Worker +{ + Runner::Runner(int pid) : processId(pid), terminate(false) + { + + } + + Runner::~Runner() + { + + } + + void Runner::run() + { + HANDLE processHandle = OpenProcess(SYNCHRONIZE, FALSE, this->processId); + if (!processHandle || processHandle == INVALID_HANDLE_VALUE) + { + printf("Unable to attach to parent process\n"); + } + else + { + printf("Successfully attached to parent process\n"); + printf("Starting worker...\n"); + + std::thread workerThread(&Runner::worker, this); + + WaitForSingleObject(processHandle, INFINITE); + CloseHandle(processHandle); + + this->terminate = true; + printf("Awaiting worker termination...\n"); + if (workerThread.joinable()) workerThread.join(); + printf("Worker terminated\n"); + } + } + + void Runner::worker() + { + printf("Worker started\n"); + Utils::IPC::BidirectionalChannel channel("iw4xChannel", !Worker::IsWorker()); + + while (!this->terminate) + { + Steam::Proxy::RunFrame(); + + std::string buffer; + if (channel.receive(&buffer)) + { + printf("Data received: %s\n", buffer.data()); + channel.send("OK " + buffer); + } + + std::this_thread::sleep_for(1ms); + } + + printf("Terminating worker\n"); + } +} diff --git a/src/Worker/Runner.hpp b/src/Worker/Runner.hpp new file mode 100644 index 00000000..4c13444b --- /dev/null +++ b/src/Worker/Runner.hpp @@ -0,0 +1,19 @@ +#pragma once + +namespace Worker +{ + class Runner + { + public: + Runner(int pid); + ~Runner(); + + void run(); + + private: + void worker(); + + int processId; + bool terminate; + }; +} diff --git a/src/Worker/STDInclude.cpp b/src/Worker/STDInclude.cpp deleted file mode 100644 index 2edc9db6..00000000 --- a/src/Worker/STDInclude.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "STDInclude.hpp" - -// Rename sections -#ifndef DEBUG -#pragma comment(linker, "/merge:.text=.UPX0") -#pragma comment(linker, "/merge:.data=.UPX1") -#pragma comment(linker, "/merge:.rdata=.UPX2") -#pragma comment(linker, "/merge:.tls=.UPX3") -#pragma comment(linker, "/merge:.gfids=.UPX4") -#endif - -#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") - -// Do necessary assertions here -// Some compilers treat them differently which causes a size mismatch - -// WinAPI types -AssertSize(DWORD, 4); -AssertSize(WORD, 2); -AssertSize(BYTE, 1); - -// 128 bit integers (only x64) -//AssertSize(__int128, 16); -//AssertSize(unsigned __int128, 16); - -// 64 bit integers -AssertSize(__int64, 8); -AssertSize(unsigned __int64, 8); -AssertSize(long long, 8); -AssertSize(unsigned long long, 8); -AssertSize(int64_t, 8); -AssertSize(uint64_t, 8); -AssertSize(std::int64_t, 8); -AssertSize(std::uint64_t, 8); - -// 32 bit integers -AssertSize(__int32, 4); -AssertSize(unsigned __int32, 4); -AssertSize(int, 4); -AssertSize(unsigned int, 4); -AssertSize(int32_t, 4); -AssertSize(uint32_t, 4); -AssertSize(std::int32_t, 4); -AssertSize(std::uint32_t, 4); - -// 16 bit integers -AssertSize(__int16, 2); -AssertSize(unsigned __int16, 2); -AssertSize(short, 2); -AssertSize(unsigned short, 2); -AssertSize(int16_t, 2); -AssertSize(uint16_t, 2); -AssertSize(std::int16_t, 2); -AssertSize(std::uint16_t, 2); - -// 8 bit integers -AssertSize(bool, 1); -AssertSize(__int8, 1); -AssertSize(unsigned __int8, 1); -AssertSize(char, 1); -AssertSize(unsigned char, 1); -AssertSize(int8_t, 1); -AssertSize(uint8_t, 1); -AssertSize(std::int8_t, 1); -AssertSize(std::uint8_t, 1); - -// Ensure pointers are 4 bytes in size (32-bit) -static_assert(sizeof(intptr_t) == 4 && sizeof(void*) == 4 && sizeof(size_t) == 4, "This doesn't seem to be a 32-bit environment!"); - -extern "C" -{ - // Disable telemetry data logging - void __cdecl __vcrt_initialize_telemetry_provider() {} - void __cdecl __telemetry_main_invoke_trigger() {} - void __cdecl __telemetry_main_return_trigger() {} - void __cdecl __vcrt_uninitialize_telemetry_provider() {} -}; diff --git a/src/Worker/STDInclude.hpp b/src/Worker/STDInclude.hpp deleted file mode 100644 index 2237256d..00000000 --- a/src/Worker/STDInclude.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#pragma once - -// Version number -#include "version.h" - -#ifndef RC_INVOKED - -#define VC_EXTRALEAN -#define WIN32_LEAN_AND_MEAN - -// Requires Visual Leak Detector plugin: http://vld.codeplex.com/ -//#include - -#include -#include -#include -#include -#include -#include - -#pragma warning(push) -#pragma warning(disable: 4996) -#include -#pragma warning(pop) - -#include -#include -#include -#include -#include -#include -#include -#include - -// Experimental C++17 features -#include - -// Usefull for debugging -template class Sizer { }; -#define BindNum(x, y) Sizer y; -#define SizeOf(x, y) BindNum(sizeof(x), y) -#define OffsetOf(x, y, z) BindNum(offsetof(x, y), z) - -// Submodules -// Ignore the warnings, it's no our code! -#pragma warning(push) -#pragma warning(disable: 4005) -#pragma warning(disable: 4100) -#pragma warning(disable: 4389) -#pragma warning(disable: 4702) -#pragma warning(disable: 4996) // _CRT_SECURE_NO_WARNINGS -#pragma warning(disable: 6001) -#pragma warning(disable: 6011) -#pragma warning(disable: 6031) -#pragma warning(disable: 6255) -#pragma warning(disable: 6258) -#pragma warning(disable: 6386) -#pragma warning(disable: 6387) - -#include - -#ifdef max -#undef max -#endif - -#ifdef min -#undef min -#endif - -// Protobuf -#include "proto/network.pb.h" -#include "proto/party.pb.h" -#include "proto/auth.pb.h" -#include "proto/node.pb.h" -#include "proto/rcon.pb.h" - -#pragma warning(pop) - -#include "../Utils/IO.hpp" -#include "../Utils/IPC.hpp" -#include "../Utils/Time.hpp" -#include "../Utils/Chain.hpp" -#include "../Utils/Utils.hpp" -#include "../Utils/WebIO.hpp" -#include "../Utils/Memory.hpp" -#include "../Utils/String.hpp" -#include "../Utils/Library.hpp" -#include "../Utils/Compression.hpp" - -// Libraries -#pragma comment(lib, "Winmm.lib") -#pragma comment(lib, "Crypt32.lib") -#pragma comment(lib, "Ws2_32.lib") -#pragma comment(lib, "d3d9.lib") -#pragma comment(lib, "Wininet.lib") -#pragma comment(lib, "shlwapi.lib") -#pragma comment(lib, "Urlmon.lib") -#pragma comment(lib, "Advapi32.lib") -#pragma comment(lib, "rpcrt4.lib") - -// Enable additional literals -using namespace std::literals; - -#endif - -#define STRINGIZE_(x) #x -#define STRINGIZE(x) STRINGIZE_(x) - -#define AssertSize(x, size) static_assert(sizeof(x) == size, STRINGIZE(x) " structure has an invalid size.") -#define AssertOffset(x, y, offset) static_assert(offsetof(x, y) == offset, STRINGIZE(x) "::" STRINGIZE(y) " is not at the right offset.") - -// Resource stuff -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -// Defines below make accessing the resources from the code easier. -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif - -// Enables custom map code -#ifdef DEBUG -#define ENABLE_EXPERIMENTAL_MAP_CODE -#endif diff --git a/src/Worker/Worker.cpp b/src/Worker/Worker.cpp new file mode 100644 index 00000000..e27c2619 --- /dev/null +++ b/src/Worker/Worker.cpp @@ -0,0 +1,65 @@ +#include "STDInclude.hpp" + +namespace Worker +{ + int ProcessId; + + int __stdcall EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, char* /*lpCmdLine*/, int /*nCmdShow*/) + { + Runner runner(Worker::ProcessId); + runner.run(); + return 0; + } + + void Initialize() + { + if(!Steam::Proxy::Inititalize()) + { + printf("Failed to initialize worker!\n"); + ExitProcess(1); + } + else + { +#ifdef DEBUG + SetConsoleTitleA("IW4x Worker"); +#else + FreeConsole(); +#endif + + Utils::Hook(0x6BABA1, Worker::EntryPoint, HOOK_CALL).install()->quick(); + } + } + + void Uninitialize() + { + Steam::Proxy::Uninititalize(); + } + + bool ParseWorkerFlag() + { + char* command = "-parent "; + char* parentProc = strstr(GetCommandLineA(), command); + + if (parentProc) + { + parentProc += strlen(command); + Worker::ProcessId = atoi(parentProc); + + return true; + } + + return false; + } + + bool IsWorker() + { + static Utils::Value flag; + + if (!flag.isValid()) + { + flag.set(Worker::ParseWorkerFlag()); + } + + return flag.get(); + } +} diff --git a/src/Worker/Worker.hpp b/src/Worker/Worker.hpp new file mode 100644 index 00000000..4f700b23 --- /dev/null +++ b/src/Worker/Worker.hpp @@ -0,0 +1,11 @@ +#pragma once + +namespace Worker +{ + void Initialize(); + void Uninitialize(); + + bool IsWorker(); +} + +#include "Runner.hpp" From d79493d6d74031021cbad62825bab1ced62712a2 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 22:04:11 +0100 Subject: [PATCH 11/14] [Steam] Only handle overlay related operations in the client --- src/Steam/Proxy.cpp | 92 ++++++++++++++------------------------------- src/Steam/Proxy.hpp | 4 +- src/Steam/Steam.cpp | 20 ++-------- 3 files changed, 32 insertions(+), 84 deletions(-) diff --git a/src/Steam/Proxy.cpp b/src/Steam/Proxy.cpp index 9b845050..e59b00ed 100644 --- a/src/Steam/Proxy.cpp +++ b/src/Steam/Proxy.cpp @@ -5,17 +5,17 @@ namespace Steam ::Utils::Library Proxy::Client; ::Utils::Library Proxy::Overlay; - ISteamClient008* Proxy::SteamClient; - IClientEngine* Proxy::ClientEngine; - IClientUser* Proxy::ClientUser; + ISteamClient008* Proxy::SteamClient = nullptr; + IClientEngine* Proxy::ClientEngine = nullptr; + IClientUser* Proxy::ClientUser = nullptr; - void* Proxy::SteamPipe; - void* Proxy::SteamUser; + void* Proxy::SteamPipe = nullptr; + void* Proxy::SteamUser = nullptr; - Friends15* Proxy::SteamFriends; - Utils* Proxy::SteamUtils; + Friends15* Proxy::SteamFriends = nullptr; + Utils* Proxy::SteamUtils = nullptr; - uint32_t Proxy::AppId; + uint32_t Proxy::AppId = 0; std::recursive_mutex Proxy::CallMutex; std::vector Proxy::Calls; @@ -29,54 +29,15 @@ namespace Steam { Proxy::AppId = appId; - SetEnvironmentVariableA("SteamAppId", ::Utils::String::VA("%lu", appId)); - SetEnvironmentVariableA("SteamGameId", ::Utils::String::VA("%llu", appId & 0xFFFFFF)); +// if (!Components::Flags::HasFlag("nosteam")) +// { +// SetEnvironmentVariableA("SteamAppId", ::Utils::String::VA("%lu", appId)); +// SetEnvironmentVariableA("SteamGameId", ::Utils::String::VA("%llu", appId & 0xFFFFFF)); +// +// ::Utils::IO::WriteFile("steam_appid.txt", ::Utils::String::VA("%lu", appId), false); +// } - ::Utils::IO::WriteFile("steam_appid.txt", ::Utils::String::VA("%lu", appId), false); - } - - void Proxy::SetMod(std::string mod) - { -#if 0 - if (!Proxy::ClientUser) return; - - GameID_t gameID; - gameID.m_nType = 1; // k_EGameIDTypeGameMod - gameID.m_nAppID = Proxy::AppId & 0xFFFFFF; - gameID.m_nModID = 0x01010101; - - char ourPath[MAX_PATH] = { 0 }; - GetModuleFileNameA(GetModuleHandle(nullptr), ourPath, sizeof(ourPath)); - - char ourDirectory[MAX_PATH] = { 0 }; - GetCurrentDirectoryA(sizeof(ourDirectory), ourDirectory); - - char blob[1] = { 0 }; - std::string cmdline = ::Utils::String::VA("\"%s\" -parentProc %d", ourPath, GetCurrentProcessId()); - Proxy::ClientUser->SpawnProcess(blob, 0, ourPath, cmdline.data(), 0, ourDirectory, gameID, Proxy::AppId, mod.data(), 0); -#endif - } - - void Proxy::RunMod() - { - char* command = "-parentProc "; - char* parentProc = strstr(GetCommandLineA(), command); - - if (parentProc) - { - parentProc += strlen(command); - int pid = atoi(parentProc); - - HANDLE processHandle = OpenProcess(SYNCHRONIZE, FALSE, pid); - - if (processHandle && processHandle != INVALID_HANDLE_VALUE) - { - WaitForSingleObject(processHandle, INFINITE); - CloseHandle(processHandle); - } - - TerminateProcess(GetCurrentProcess(), 0); - } + remove("steam_appid.txt"); } void Proxy::RegisterCall(int32_t callId, uint32_t size, uint64_t call) @@ -142,13 +103,13 @@ namespace Steam } Proxy::CallbackMsg message; - while (Proxy::SteamBGetCallback(Proxy::SteamPipe, &message)) + while (Proxy::SteamBGetCallback && Proxy::SteamFreeLastCallback && Proxy::SteamBGetCallback(Proxy::SteamPipe, &message)) { #ifdef DEBUG - Components::Logger::Print("Steam::Proxy: Callback dispatched: %d\n", message.m_iCallback); + printf("Callback dispatched: %d\n", message.m_iCallback); #endif - Steam::Callbacks::RunCallback(message.m_iCallback, message.m_pubParam); + //Steam::Callbacks::RunCallback(message.m_iCallback, message.m_pubParam); Proxy::RunCallback(message.m_iCallback, message.m_pubParam); Proxy::SteamFreeLastCallback(Proxy::SteamPipe); } @@ -163,7 +124,7 @@ namespace Steam ::Utils::Memory::Allocator allocator; #ifdef DEBUG - Components::Logger::Print("Steam::Proxy: Handling call: %d\n", call.callId); + printf("Handling call: %d\n", call.callId); #endif call.handled = true; @@ -172,7 +133,7 @@ namespace Steam { #ifdef DEBUG auto error = Proxy::SteamUtils->GetAPICallFailureReason(call.call); - Components::Logger::Print("Steam::Proxy: API call failed: %X Handle: %llX\n", error, call.call); + printf("API call failed: %X Handle: %llX\n", error, call.call); #endif continue; } @@ -185,7 +146,7 @@ namespace Steam { #ifdef DEBUG auto error = Proxy::SteamUtils->GetAPICallFailureReason(call.call); - Components::Logger::Print("Steam::Proxy: GetAPICallResult failed: %X Handle: %llX\n", error, call.call); + printf("GetAPICallResult failed: %X Handle: %llX\n", error, call.call); #endif continue; } @@ -198,16 +159,19 @@ namespace Steam Proxy::UnregisterCalls(); } - bool Proxy::Inititalize() + bool Proxy::Inititalize(bool overlayOnly) { std::string directoy = Proxy::GetSteamDirectory(); if (directoy.empty()) return false; SetDllDirectoryA(Proxy::GetSteamDirectory().data()); - Proxy::Client = ::Utils::Library(STEAMCLIENT_LIB, false); Proxy::Overlay = ::Utils::Library(GAMEOVERLAY_LIB, false); - if (!Proxy::Client.valid() || !Proxy::Overlay.valid()) return false; + if (!Proxy::Overlay.valid()) return false; + if (overlayOnly) return true; + + Proxy::Client = ::Utils::Library(STEAMCLIENT_LIB, false); + if (!Proxy::Client.valid()) return false; Proxy::SteamClient = Proxy::Client.get("CreateInterface")("SteamClient008", nullptr); if(!Proxy::SteamClient) return false; diff --git a/src/Steam/Proxy.hpp b/src/Steam/Proxy.hpp index a729e9ce..fe974175 100644 --- a/src/Steam/Proxy.hpp +++ b/src/Steam/Proxy.hpp @@ -334,12 +334,10 @@ namespace Steam class Proxy { public: - static bool Inititalize(); + static bool Inititalize(bool overlayOnly = false); static void Uninititalize(); static void SetGame(uint32_t appId); - static void SetMod(std::string mod); - static void RunMod(); //Overlay related proxies static void SetOverlayNotificationPosition(uint32_t eNotificationPosition); diff --git a/src/Steam/Steam.cpp b/src/Steam/Steam.cpp index bfa450ac..d8e5580a 100644 --- a/src/Steam/Steam.cpp +++ b/src/Steam/Steam.cpp @@ -106,26 +106,12 @@ namespace Steam { bool SteamAPI_Init() { -#ifndef DISABLE_STEAM_GAME - if (!Components::Flags::HasFlag("nosteam")) - { - //Proxy::SetGame(10190); - } -#endif + Proxy::SetGame(10190); - if (!Proxy::Inititalize()) + if (!Proxy::Inititalize(true)) { OutputDebugStringA("Steamproxy not initialized properly"); } - else - { -#ifndef DISABLE_STEAM_GAME - if (!Components::Flags::HasFlag("nosteam")) - { - //Proxy::SetMod("IW4x - Modern Warfare 2"); - } -#endif - } return true; } @@ -143,7 +129,7 @@ namespace Steam void SteamAPI_RunCallbacks() { Callbacks::RunCallbacks(); - Proxy::RunFrame(); + //Proxy::RunFrame(); } void SteamAPI_Shutdown() From 38d0ca616a3b540f74d286d18f1f561f3735c497 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 22:04:26 +0100 Subject: [PATCH 12/14] [AntiCheat] Reenable process protection --- src/Components/Modules/AntiCheat.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/AntiCheat.hpp b/src/Components/Modules/AntiCheat.hpp index 4c32f9ee..63ac9b24 100644 --- a/src/Components/Modules/AntiCheat.hpp +++ b/src/Components/Modules/AntiCheat.hpp @@ -6,7 +6,7 @@ #endif // Uncomment to enable process protection (conflicts with steam!) -//#define PROCTECT_PROCESS +#define PROCTECT_PROCESS namespace Components { From 559195c5cc521d818b3efc5661d12c18b60a2a08 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 22:45:01 +0100 Subject: [PATCH 13/14] [IPCHandler] Register basic ipc handler --- src/Components/Loader.cpp | 2 +- src/Components/Loader.hpp | 2 +- src/Components/Modules/ConnectProtocol.cpp | 10 +- src/Components/Modules/IPCHandler.cpp | 83 ++++++ src/Components/Modules/IPCHandler.hpp | 33 +++ src/Components/Modules/IPCPipe.cpp | 296 --------------------- src/Components/Modules/IPCPipe.hpp | 83 ------ src/Proto/ipc.proto | 9 + src/STDInclude.hpp | 1 + src/Worker/Runner.cpp | 4 +- 10 files changed, 135 insertions(+), 388 deletions(-) create mode 100644 src/Components/Modules/IPCHandler.cpp create mode 100644 src/Components/Modules/IPCHandler.hpp delete mode 100644 src/Components/Modules/IPCPipe.cpp delete mode 100644 src/Components/Modules/IPCPipe.hpp create mode 100644 src/Proto/ipc.proto diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 7e731941..7afac788 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -43,7 +43,6 @@ namespace Components Loader::Register(new Command()); Loader::Register(new Console()); Loader::Register(new Friends()); - Loader::Register(new IPCPipe()); Loader::Register(new ModList()); Loader::Register(new Network()); Loader::Register(new Theatre()); @@ -68,6 +67,7 @@ namespace Components Loader::Register(new BitMessage()); #endif Loader::Register(new FileSystem()); + Loader::Register(new IPCHandler()); Loader::Register(new ModelSurfs()); Loader::Register(new PlayerName()); Loader::Register(new QuickPatch()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 696897ae..f9da13d3 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -59,7 +59,6 @@ namespace Components #include "Modules/Window.hpp" #include "Modules/Command.hpp" #include "Modules/Console.hpp" -#include "Modules/IPCPipe.hpp" #include "Modules/UIScript.hpp" #include "Modules/ModList.hpp" #include "Modules/Network.hpp" @@ -86,6 +85,7 @@ namespace Components #include "Modules/Threading.hpp" #include "Modules/BitMessage.hpp" #include "Modules/FileSystem.hpp" +#include "Modules/IPCHandler.hpp" #include "Modules/ModelSurfs.hpp" #include "Modules/PlayerName.hpp" #include "Modules/QuickPatch.hpp" diff --git a/src/Components/Modules/ConnectProtocol.cpp b/src/Components/Modules/ConnectProtocol.cpp index defdd32f..44b417f4 100644 --- a/src/Components/Modules/ConnectProtocol.cpp +++ b/src/Components/Modules/ConnectProtocol.cpp @@ -212,10 +212,10 @@ namespace Components ConnectProtocol::ConnectProtocol() { // IPC handler - IPCPipe::On("connect", [] (std::string data) - { - Command::Execute(Utils::String::VA("connect %s", data.data()), false); - }); +// IPCPipe::On("connect", [] (std::string data) +// { +// Command::Execute(Utils::String::VA("connect %s", data.data()), false); +// }); // Invocation handler QuickPatch::Once(ConnectProtocol::Invocation); @@ -229,7 +229,7 @@ namespace Components { if (!Singleton::IsFirstInstance()) { - IPCPipe::Write("connect", ConnectProtocol::ConnectString); + //IPCPipe::Write("connect", ConnectProtocol::ConnectString); ExitProcess(0); } else diff --git a/src/Components/Modules/IPCHandler.cpp b/src/Components/Modules/IPCHandler.cpp new file mode 100644 index 00000000..d0c66eb4 --- /dev/null +++ b/src/Components/Modules/IPCHandler.cpp @@ -0,0 +1,83 @@ +#include "STDInclude.hpp" + +namespace Components +{ + std::unordered_map IPCHandler::WorkerCallbacks; + std::unordered_map IPCHandler::ClientCallbacks; + + std::unique_ptr IPCHandler::WorkerChannel; + std::unique_ptr IPCHandler::ClientChannel; + + void IPCHandler::SendWorker(std::string message, std::string data) + { + IPCHandler::InitChannels(); + + } + + void IPCHandler::SendClient(std::string message, std::string data) + { + IPCHandler::InitChannels(); + //IPCHandler::ClientChannel->send() + } + + void IPCHandler::OnWorker(std::string message, IPCHandler::Callback callback) + { + IPCHandler::WorkerCallbacks[message] = callback; + } + + void IPCHandler::OnClient(std::string message, IPCHandler::Callback callback) + { + IPCHandler::ClientCallbacks[message] = callback; + } + + void IPCHandler::InitChannels() + { + if (!IPCHandler::WorkerChannel) + { + IPCHandler::WorkerChannel.reset(new Utils::IPC::BidirectionalChannel("IW4x-Worker-Channel", !Worker::IsWorker())); + } + + if (!IPCHandler::ClientChannel) + { + IPCHandler::ClientChannel.reset(new Utils::IPC::BidirectionalChannel("IW4x-Client-Channel", Singleton::IsFirstInstance())); + } + } + + void IPCHandler::StartWorker() + { + STARTUPINFOA sInfo; + PROCESS_INFORMATION pInfo; + + ZeroMemory(&sInfo, sizeof(sInfo)); + ZeroMemory(&pInfo, sizeof(pInfo)); + sInfo.cb = sizeof(sInfo); + + CreateProcessA("iw4x.exe", const_cast(Utils::String::VA("-parent %d", GetCurrentProcessId())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo); + + if (pInfo.hThread && pInfo.hThread != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hThread); + if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hProcess); + } + + IPCHandler::IPCHandler() + { + if (Dedicated::IsEnabled()) return; + + IPCHandler::InitChannels(); + IPCHandler::StartWorker(); + + QuickPatch::OnFrame([]() + { + std::string buffer; + if(IPCHandler::WorkerChannel->receive(&buffer)) + { + Logger::Print("Data received: %s\n", buffer.data()); + } + }); + } + + IPCHandler::~IPCHandler() + { + IPCHandler::WorkerCallbacks.clear(); + IPCHandler::ClientCallbacks.clear(); + } +} diff --git a/src/Components/Modules/IPCHandler.hpp b/src/Components/Modules/IPCHandler.hpp new file mode 100644 index 00000000..d9d2f72e --- /dev/null +++ b/src/Components/Modules/IPCHandler.hpp @@ -0,0 +1,33 @@ +#pragma once + +namespace Components +{ + class IPCHandler : public Component + { + public: + typedef Utils::Slot Callback; + + IPCHandler(); + ~IPCHandler(); + +#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) + const char* getName() override { return "IPCHandler"; }; +#endif + + void SendWorker(std::string message, std::string data); + void SendClient(std::string message, std::string data); + + void OnWorker(std::string message, Callback callback); + void OnClient(std::string message, Callback callback); + + private: + static std::unique_ptr WorkerChannel; + static std::unique_ptr ClientChannel; + + static std::unordered_map WorkerCallbacks; + static std::unordered_map ClientCallbacks; + + static void InitChannels(); + static void StartWorker(); + }; +} diff --git a/src/Components/Modules/IPCPipe.cpp b/src/Components/Modules/IPCPipe.cpp deleted file mode 100644 index 1b558082..00000000 --- a/src/Components/Modules/IPCPipe.cpp +++ /dev/null @@ -1,296 +0,0 @@ -#include "STDInclude.hpp" - -namespace Components -{ - Pipe IPCPipe::ServerPipe; - Pipe IPCPipe::ClientPipe; - -#pragma region Pipe - - Pipe::Pipe() : connectCallback(0), pipe(INVALID_HANDLE_VALUE), threadAttached(false), type(IPCTYPE_NONE), reconnectAttempt(0) - { - this->destroy(); - } - - Pipe::~Pipe() - { - this->destroy(); - } - - bool Pipe::connect(std::string name) - { - this->destroy(); - - this->type = IPCTYPE_CLIENT; - this->setName(name); - - this->pipe = CreateFileA(this->pipeFile, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); - - if (INVALID_HANDLE_VALUE == this->pipe) - { - Logger::Print("Failed to connect to the pipe\n"); - - if (this->reconnectAttempt < IPC_MAX_RECONNECTS) - { - Logger::Print("Attempting to reconnect to the pipe.\n"); - ++this->reconnectAttempt; - std::this_thread::sleep_for(500ms); - - return this->connect(name); - } - else - { - this->destroy(); - return false; - } - } - - this->reconnectAttempt = 0; - Logger::Print("Successfully connected to the pipe\n"); - - return true; - } - - bool Pipe::create(std::string name) - { - this->destroy(); - - this->type = IPCTYPE_SERVER; - this->setName(name); - - this->pipe = CreateNamedPipeA(this->pipeFile, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, sizeof(this->packet), sizeof(this->packet), NMPWAIT_USE_DEFAULT_WAIT, nullptr); - - if (INVALID_HANDLE_VALUE != this->pipe && this->pipe) - { - // Only create the thread, when not performing unit tests! - if (!Loader::PerformingUnitTests()) - { - this->threadAttached = true; - this->thread = std::thread(Pipe::ReceiveThread, this); - } - - Logger::Print("Pipe successfully created\n"); - return true; - } - - Logger::Print("Failed to create the pipe\n"); - this->destroy(); - return false; - } - - void Pipe::onConnect(Pipe::Callback callback) - { - this->connectCallback = callback; - } - - void Pipe::setCallback(std::string command, Utils::Slot callback) - { - this->packetCallbacks[command] = callback; - } - - bool Pipe::write(std::string command, std::string data) - { - if (this->type != IPCTYPE_CLIENT || this->pipe == INVALID_HANDLE_VALUE) return false; - - Pipe::Packet _packet; - strcpy_s(_packet.command, command.data()); - strcpy_s(_packet.buffer, data.data()); - - DWORD cbBytes; - return (WriteFile(this->pipe, &_packet, sizeof(_packet), &cbBytes, nullptr) || GetLastError() == ERROR_IO_PENDING); - } - - void Pipe::destroy() - { - //this->Type = IPCTYPE_NONE; - - //*this->PipeFile = 0; - //*this->PipeName = 0; - - if (this->pipe && INVALID_HANDLE_VALUE != this->pipe) - { - CancelIoEx(this->pipe, nullptr); - //DeleteFileA(this->pipeFile); - - if (this->type == IPCTYPE_SERVER) DisconnectNamedPipe(this->pipe); - - CloseHandle(this->pipe); - Logger::Print("Disconnected from the pipe.\n"); - } - - this->pipe = nullptr; - this->threadAttached = false; - - if (this->thread.joinable()) - { - Logger::Print("Terminating pipe thread...\n"); - - this->thread.join(); - - Logger::Print("Pipe thread terminated.\n"); - } - - this->thread = std::thread(); - } - - void Pipe::setName(std::string name) - { - memset(this->pipeName, 0, sizeof(this->pipeName)); - memset(this->pipeFile, 0, sizeof(this->pipeFile)); - - strncpy_s(this->pipeName, name.data(), sizeof(this->pipeName)); - sprintf_s(this->pipeFile, sizeof(this->pipeFile), "\\\\.\\Pipe\\%s", this->pipeName); - } - - void Pipe::ReceiveThread(Pipe* pipe) - { - if (!pipe || pipe->type != IPCTYPE_SERVER || pipe->pipe == INVALID_HANDLE_VALUE || !pipe->pipe) return; - - if (ConnectNamedPipe(pipe->pipe, nullptr) == FALSE) - { - Logger::Print("Failed to initialize pipe reading.\n"); - return; - } - - Logger::Print("Client connected to the pipe\n"); - pipe->connectCallback(); - - DWORD cbBytes; - - while (pipe->threadAttached && pipe->pipe && pipe->pipe != INVALID_HANDLE_VALUE) - { - BOOL bResult = ReadFile(pipe->pipe, &pipe->packet, sizeof(pipe->packet), &cbBytes, nullptr); - - if (bResult && cbBytes) - { - if (pipe->packetCallbacks.find(pipe->packet.command) != pipe->packetCallbacks.end()) - { - pipe->packetCallbacks[pipe->packet.command](pipe->packet.buffer); - } - } - else if (pipe->threadAttached && pipe->pipe != INVALID_HANDLE_VALUE) - { - Logger::Print("Failed to read from client through pipe\n"); - - DisconnectNamedPipe(pipe->pipe); - ConnectNamedPipe(pipe->pipe, nullptr); - pipe->connectCallback(); - } - - ZeroMemory(&pipe->packet, sizeof(pipe->packet)); - } - } - -#pragma endregion - - // Callback to connect first instance's client pipe to the second instance's server pipe - void IPCPipe::ConnectClient() - { - if (Singleton::IsFirstInstance()) - { - IPCPipe::ClientPipe.connect(IPC_PIPE_NAME_CLIENT); - } - } - - // Writes to the process on the other end of the pipe - bool IPCPipe::Write(std::string command, std::string data) - { - return IPCPipe::ClientPipe.write(command, data); - } - - // Installs a callback for receiving commands from the process on the other end of the pipe - void IPCPipe::On(std::string command, Utils::Slot callback) - { - IPCPipe::ServerPipe.setCallback(command, callback); - } - - IPCPipe::IPCPipe() - { - if (Dedicated::IsEnabled()) return; - - // Server pipe - IPCPipe::ServerPipe.onConnect(IPCPipe::ConnectClient); - IPCPipe::ServerPipe.create((Singleton::IsFirstInstance() ? IPC_PIPE_NAME_SERVER : IPC_PIPE_NAME_CLIENT)); - - // Connect second instance's client pipe to first instance's server pipe - if (!Singleton::IsFirstInstance()) - { - IPCPipe::ClientPipe.connect(IPC_PIPE_NAME_SERVER); - } - - IPCPipe::On("ping", [] (std::string data) - { - Logger::Print("Received ping form pipe, sending pong!\n"); - IPCPipe::Write("pong", data); - }); - - IPCPipe::On("pong", [] (std::string data) - { - Logger::Print("Received pong form pipe!\n"); - }); - - // Test pipe functionality by sending pings - Command::Add("ipcping", [] (Command::Params*) - { - Logger::Print("Sending ping to pipe!\n"); - IPCPipe::Write("ping", ""); - }); - - static Utils::IPC::BidirectionalChannel channel("iw4xChannel", !Worker::IsWorker()); - channel.send("Hello world!"); - - Command::Add("ipcchan", [](Command::Params* params) - { - channel.send(params->join(1)); - }); - - Command::Add("ipcchantest", [](Command::Params*) - { - std::string buffer; - buffer.reserve(2048); - - for(int i = 0; i < 1020; ++i) - { - buffer.append("a", 1); - } - - buffer.append("lolsnakerules!"); - - for (int i = 0; i < 1020; ++i) - { - buffer.append("a", 1); - } - - buffer.append("lolsnakerules!"); - - channel.send(buffer); - }); - - QuickPatch::OnFrame([]() - { - std::string buffer; - if(channel.receive(&buffer)) - { - Logger::Print("Data received: %s\n", buffer.data()); - } - }); - - STARTUPINFOA sInfo; - PROCESS_INFORMATION pInfo; - - ZeroMemory(&sInfo, sizeof(sInfo)); - ZeroMemory(&pInfo, sizeof(pInfo)); - sInfo.cb = sizeof(sInfo); - - CreateProcessA("iw4x.exe", const_cast(Utils::String::VA("-parent %d", GetCurrentProcessId())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo); - - if (pInfo.hThread && pInfo.hThread != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hThread); - if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hProcess); - } - - void IPCPipe::preDestroy() - { - IPCPipe::ServerPipe.destroy(); - IPCPipe::ClientPipe.destroy(); - } -} diff --git a/src/Components/Modules/IPCPipe.hpp b/src/Components/Modules/IPCPipe.hpp deleted file mode 100644 index 58bbc713..00000000 --- a/src/Components/Modules/IPCPipe.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#define IPC_MAX_RECONNECTS 3 -#define IPC_COMMAND_SIZE 100 -#define IPC_BUFFER_SIZE 0x2000 - -#define IPC_PIPE_NAME_SERVER "IW4x-Server" -#define IPC_PIPE_NAME_CLIENT "IW4x-Client" - -namespace Components -{ - class Pipe - { - public: - struct Packet - { - char command[IPC_COMMAND_SIZE]; - char buffer[IPC_BUFFER_SIZE]; - }; - - enum Type - { - IPCTYPE_NONE, - IPCTYPE_SERVER, - IPCTYPE_CLIENT - }; - - typedef void(__cdecl PacketCallback)(std::string data); - typedef void(__cdecl Callback)(); - - Pipe(); - ~Pipe(); - - bool connect(std::string name); - bool create(std::string name); - - bool write(std::string command, std::string data); - void setCallback(std::string command, Utils::Slot callback); - void onConnect(Callback callback); - - void destroy(); - - private: - Utils::Slot connectCallback; - std::map> packetCallbacks; - - HANDLE pipe; - std::thread thread; - bool threadAttached; - - Type type; - Packet packet; - - char pipeName[MAX_PATH]; - char pipeFile[MAX_PATH]; - unsigned int reconnectAttempt; - - void setName(std::string name); - - static void ReceiveThread(Pipe* pipe); - }; - - class IPCPipe : public Component - { - public: - IPCPipe(); - -#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) - const char* getName() override { return "IPCPipe"; }; -#endif - - void preDestroy() override; - - static bool Write(std::string command, std::string data); - static void On(std::string command, Utils::Slot callback); - - private: - static Pipe ServerPipe; - static Pipe ClientPipe; - - static void ConnectClient(); - }; -} diff --git a/src/Proto/ipc.proto b/src/Proto/ipc.proto new file mode 100644 index 00000000..f2e71514 --- /dev/null +++ b/src/Proto/ipc.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package Proto.IPC; + +message Command +{ + bytes command = 1; + bytes data = 2; +} diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index d6cb65ab..971715fd 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -85,6 +85,7 @@ template class Sizer { }; #include "proto/auth.pb.h" #include "proto/node.pb.h" #include "proto/rcon.pb.h" +#include "proto/ipc.pb.h" #pragma warning(pop) diff --git a/src/Worker/Runner.cpp b/src/Worker/Runner.cpp index 19e56d93..be4b63a1 100644 --- a/src/Worker/Runner.cpp +++ b/src/Worker/Runner.cpp @@ -29,8 +29,8 @@ namespace Worker WaitForSingleObject(processHandle, INFINITE); CloseHandle(processHandle); - this->terminate = true; printf("Awaiting worker termination...\n"); + this->terminate = true; if (workerThread.joinable()) workerThread.join(); printf("Worker terminated\n"); } @@ -39,7 +39,7 @@ namespace Worker void Runner::worker() { printf("Worker started\n"); - Utils::IPC::BidirectionalChannel channel("iw4xChannel", !Worker::IsWorker()); + Utils::IPC::BidirectionalChannel channel("IW4x-Worker-Channel", !Worker::IsWorker()); while (!this->terminate) { From ee185c538fe5b42618fafd8f2a82c9bcdbd05ec9 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 27 Jan 2017 23:09:32 +0100 Subject: [PATCH 14/14] [ConnectProtocol] Upgrade the protocol to the new ipc infrastructure --- src/Components/Modules/ConnectProtocol.cpp | 10 ++-- src/Components/Modules/IPCHandler.cpp | 57 +++++++++++++++++++--- src/Components/Modules/IPCHandler.hpp | 11 +++-- src/Utils/IPC.cpp | 8 +-- src/Utils/IPC.hpp | 3 +- 5 files changed, 69 insertions(+), 20 deletions(-) diff --git a/src/Components/Modules/ConnectProtocol.cpp b/src/Components/Modules/ConnectProtocol.cpp index 44b417f4..a70201ee 100644 --- a/src/Components/Modules/ConnectProtocol.cpp +++ b/src/Components/Modules/ConnectProtocol.cpp @@ -212,10 +212,10 @@ namespace Components ConnectProtocol::ConnectProtocol() { // IPC handler -// IPCPipe::On("connect", [] (std::string data) -// { -// Command::Execute(Utils::String::VA("connect %s", data.data()), false); -// }); + IPCHandler::OnClient("connect", [] (std::string data) + { + Command::Execute(Utils::String::VA("connect %s", data.data()), false); + }); // Invocation handler QuickPatch::Once(ConnectProtocol::Invocation); @@ -229,7 +229,7 @@ namespace Components { if (!Singleton::IsFirstInstance()) { - //IPCPipe::Write("connect", ConnectProtocol::ConnectString); + IPCHandler::SendClient("connect", ConnectProtocol::ConnectString); ExitProcess(0); } else diff --git a/src/Components/Modules/IPCHandler.cpp b/src/Components/Modules/IPCHandler.cpp index d0c66eb4..952035e4 100644 --- a/src/Components/Modules/IPCHandler.cpp +++ b/src/Components/Modules/IPCHandler.cpp @@ -12,12 +12,22 @@ namespace Components { IPCHandler::InitChannels(); + Proto::IPC::Command command; + command.set_command(message); + command.set_data(data); + + IPCHandler::WorkerChannel->send(command.SerializeAsString()); } void IPCHandler::SendClient(std::string message, std::string data) { IPCHandler::InitChannels(); - //IPCHandler::ClientChannel->send() + + Proto::IPC::Command command; + command.set_command(message); + command.set_data(data); + + IPCHandler::ClientChannel->send(command.SerializeAsString()); } void IPCHandler::OnWorker(std::string message, IPCHandler::Callback callback) @@ -58,6 +68,44 @@ namespace Components if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hProcess); } + void IPCHandler::HandleClient() + { + IPCHandler::InitChannels(); + + std::string packet; + if(IPCHandler::ClientChannel->receive(&packet)) + { + Proto::IPC::Command command; + if(command.ParseFromString(packet)) + { + auto callback = IPCHandler::ClientCallbacks.find(command.command()); + if (callback != IPCHandler::ClientCallbacks.end()) + { + callback->second(command.data()); + } + } + } + } + + void IPCHandler::HandleWorker() + { + IPCHandler::InitChannels(); + + std::string packet; + if (IPCHandler::WorkerChannel->receive(&packet)) + { + Proto::IPC::Command command; + if (command.ParseFromString(packet)) + { + auto callback = IPCHandler::WorkerCallbacks.find(command.command()); + if (callback != IPCHandler::WorkerCallbacks.end()) + { + callback->second(command.data()); + } + } + } + } + IPCHandler::IPCHandler() { if (Dedicated::IsEnabled()) return; @@ -67,11 +115,8 @@ namespace Components QuickPatch::OnFrame([]() { - std::string buffer; - if(IPCHandler::WorkerChannel->receive(&buffer)) - { - Logger::Print("Data received: %s\n", buffer.data()); - } + IPCHandler::HandleWorker(); + IPCHandler::HandleClient(); }); } diff --git a/src/Components/Modules/IPCHandler.hpp b/src/Components/Modules/IPCHandler.hpp index d9d2f72e..d63ac912 100644 --- a/src/Components/Modules/IPCHandler.hpp +++ b/src/Components/Modules/IPCHandler.hpp @@ -14,11 +14,11 @@ namespace Components const char* getName() override { return "IPCHandler"; }; #endif - void SendWorker(std::string message, std::string data); - void SendClient(std::string message, std::string data); + static void SendWorker(std::string message, std::string data); + static void SendClient(std::string message, std::string data); - void OnWorker(std::string message, Callback callback); - void OnClient(std::string message, Callback callback); + static void OnWorker(std::string message, Callback callback); + static void OnClient(std::string message, Callback callback); private: static std::unique_ptr WorkerChannel; @@ -29,5 +29,8 @@ namespace Components static void InitChannels(); static void StartWorker(); + + static void HandleClient(); + static void HandleWorker(); }; } diff --git a/src/Utils/IPC.cpp b/src/Utils/IPC.cpp index 79ab2c86..3e133b9e 100644 --- a/src/Utils/IPC.cpp +++ b/src/Utils/IPC.cpp @@ -4,15 +4,15 @@ namespace Utils { namespace IPC { - Channel::Channel(std::string _name, int queueSize, int bufferSize, bool creator) : name(_name) + Channel::Channel(std::string _name, int _queueSize, int _bufferSize, bool _remove) : name(_name), remove(_remove) { - if(creator) boost::interprocess::message_queue::remove(this->name.data()); - queue.reset(new boost::interprocess::message_queue(boost::interprocess::open_or_create, this->name.data(), queueSize, bufferSize + sizeof(Channel::Header))); + if(this->remove) boost::interprocess::message_queue::remove(this->name.data()); + queue.reset(new boost::interprocess::message_queue(boost::interprocess::open_or_create, this->name.data(), _queueSize, _bufferSize + sizeof(Channel::Header))); } Channel::~Channel() { - boost::interprocess::message_queue::remove(this->name.data()); + if (this->remove) boost::interprocess::message_queue::remove(this->name.data()); } bool Channel::receive(std::string* data) diff --git a/src/Utils/IPC.hpp b/src/Utils/IPC.hpp index 7d91c9d4..01fc080c 100644 --- a/src/Utils/IPC.hpp +++ b/src/Utils/IPC.hpp @@ -29,7 +29,7 @@ namespace Utils class Channel { public: - Channel(std::string _name, int queueSize = 100, int bufferSize = 1024, bool creator = false); + Channel(std::string _name, int _queueSize = 100, int _bufferSize = 1024, bool _remove = false); ~Channel(); bool receive(std::string* data); @@ -47,6 +47,7 @@ namespace Utils void sendMessage(std::string data); + bool remove; std::unique_ptr queue; std::string packet; std::string name;