diff --git a/bin/dx9_overlay.dll b/bin/dx9_overlay.dll index 816b8bd..d5c81d9 100644 Binary files a/bin/dx9_overlay.dll and b/bin/dx9_overlay.dll differ diff --git a/bin/dx9_overlay.exp b/bin/dx9_overlay.exp index 82acbea..85843ea 100644 Binary files a/bin/dx9_overlay.exp and b/bin/dx9_overlay.exp differ diff --git a/bin/dx9_overlay.lib b/bin/dx9_overlay.lib index 6ef120f..3b8da86 100644 Binary files a/bin/dx9_overlay.lib and b/bin/dx9_overlay.lib differ diff --git a/src/dx9_overlay/Client/Client.cpp b/src/dx9_overlay/Client/Client.cpp index 93ef313..5a1c477 100644 --- a/src/dx9_overlay/Client/Client.cpp +++ b/src/dx9_overlay/Client/Client.cpp @@ -29,7 +29,7 @@ bool IsServerAvailable() bsIn << PipeMessages::Ping; - return CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success(); + return CNamedPipeClient(bsIn, bsOut).Success(); } EXPORT void SetParam(char *_szParamName, char *_szParamValue) diff --git a/src/dx9_overlay/Client/Render.cpp b/src/dx9_overlay/Client/Render.cpp index 13305e5..10eb842 100644 --- a/src/dx9_overlay/Client/Render.cpp +++ b/src/dx9_overlay/Client/Render.cpp @@ -19,7 +19,7 @@ EXPORT int TextCreate(char *Font, int FontSize, bool bBold, bool bItalic, int x, bsIn << PipeMessages::TextCreate << std::string(Font) << FontSize << bBold << bItalic << x << y << color << std::string(text); bsIn << bShadow << bShow; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return -1; @@ -33,7 +33,7 @@ EXPORT int TextDestroy(int Id) bsIn << PipeMessages::TextDestroy << Id; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -47,7 +47,7 @@ EXPORT int TextSetShadow(int id, bool b) bsIn << PipeMessages::TextSetShadow << id << b; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -61,7 +61,7 @@ EXPORT int TextSetShown(int id, bool b) bsIn << PipeMessages::TextSetShown << id << b; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -75,7 +75,7 @@ EXPORT int TextSetColor(int id, unsigned int color) bsIn << PipeMessages::TextSetColor << id << color; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -89,7 +89,7 @@ EXPORT int TextSetPos(int id, int x, int y) bsIn << PipeMessages::TextSetPos << id << x << y; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -103,7 +103,7 @@ EXPORT int TextSetString(int id, char *str) bsIn << PipeMessages::TextSetString << id << std::string(str); - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -117,7 +117,7 @@ EXPORT int TextUpdate(int id, char *Font, int FontSize, bool bBold, bool bItalic bsIn << PipeMessages::TextUpdate << id << std::string(Font) << FontSize << bBold << bItalic; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -131,7 +131,7 @@ EXPORT int BoxCreate(int x, int y, int w, int h, unsigned int dwColor, bool bSho bsIn << PipeMessages::BoxCreate << x << y << w << h << dwColor << bShow; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return -1; @@ -145,7 +145,7 @@ EXPORT int BoxDestroy(int id) bsIn << PipeMessages::BoxDestroy << id; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -159,7 +159,7 @@ EXPORT int BoxSetShown(int id, bool bShown) bsIn << PipeMessages::BoxSetShown << id << bShown; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -173,7 +173,7 @@ EXPORT int BoxSetBorder(int id, int height, bool bShown) bsIn << PipeMessages::BoxSetBorder << id << height << bShown; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -187,7 +187,7 @@ EXPORT int BoxSetBorderColor(int id, unsigned int dwColor) bsIn << PipeMessages::BoxSetBorderColor << id << dwColor; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -201,7 +201,7 @@ EXPORT int BoxSetColor(int id, unsigned int dwColor) bsIn << PipeMessages::BoxSetColor << id << dwColor; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -215,7 +215,7 @@ EXPORT int BoxSetHeight(int id, int height) bsIn << PipeMessages::BoxSetHeight << id << height; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -229,7 +229,7 @@ EXPORT int BoxSetPos(int id, int x, int y) bsIn << PipeMessages::BoxSetPos << id << x << y; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -243,7 +243,7 @@ EXPORT int BoxSetWidth(int id, int width) bsIn << PipeMessages::BoxSetWidth << id << width; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -257,7 +257,7 @@ EXPORT int LineCreate(int x1, int y1, int x2, int y2, int width, unsigned int co bsIn << PipeMessages::LineCreate << x1 << y1 << x2 << y2 << width << color << bShow; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return -1; @@ -271,7 +271,7 @@ EXPORT int LineDestroy(int id) bsIn << PipeMessages::LineDestroy << id; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -285,7 +285,7 @@ EXPORT int LineSetShown(int id, bool bShown) bsIn << PipeMessages::LineSetShown << id << bShown; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -299,7 +299,7 @@ EXPORT int LineSetColor(int id, unsigned int color) bsIn << PipeMessages::LineSetColor << id << color; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -313,7 +313,7 @@ EXPORT int LineSetWidth(int id, int width) bsIn << PipeMessages::LineSetWidth << id << width; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -327,7 +327,7 @@ EXPORT int LineSetPos(int id, int x1, int y1, int x2, int y2) bsIn << PipeMessages::LineSetPos << id << x1 << y1 << x2 << y2; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -345,7 +345,7 @@ EXPORT int ImageCreate(char *path, int x, int y, int rotation, int align, bool b bsIn << PipeMessages::ImageCreate << abs_path << x << y << rotation << align << bShow; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return -1; @@ -359,7 +359,7 @@ EXPORT int ImageDestroy(int id) bsIn << PipeMessages::ImageDestroy << id; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -373,7 +373,7 @@ EXPORT int ImageSetShown(int id, bool bShown) bsIn << PipeMessages::ImageSetShown << id << bShown; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -387,7 +387,7 @@ EXPORT int ImageSetAlign(int id, int align) bsIn << PipeMessages::ImageSetAlign << id << align; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -401,7 +401,7 @@ EXPORT int ImageSetPos(int id, int x, int y) bsIn << PipeMessages::ImageSetPos << id << x << y; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -415,7 +415,7 @@ EXPORT int ImageSetRotation(int id, int rotation) bsIn << PipeMessages::ImageSetRotation << id << rotation; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return 0; @@ -429,7 +429,7 @@ EXPORT int DestroyAllVisual() bsIn << PipeMessages::DestroyAllVisual; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) return 1; return 0; @@ -443,7 +443,7 @@ EXPORT int ShowAllVisual() bsIn << PipeMessages::ShowAllVisual; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) return 1; return 0; @@ -457,7 +457,7 @@ EXPORT int HideAllVisual() bsIn << PipeMessages::HideAllVisual; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) return 1; return 0; @@ -471,7 +471,7 @@ EXPORT int GetFrameRate() bsIn << PipeMessages::GetFrameRate; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) BITSTREAM_RET(int); return -1; @@ -485,7 +485,7 @@ EXPORT int GetScreenSpecs(int& width, int& height) bsIn << PipeMessages::GetScreenSpecs; - if (CNamedPipeClient("Overlay_Server", bsIn, bsOut).Success()) + if (CNamedPipeClient(bsIn, bsOut).Success()) { bsOut >> width >> height; return 1; diff --git a/src/dx9_overlay/Game/Game.cpp b/src/dx9_overlay/Game/Game.cpp index 110ffd1..bba4c7b 100644 --- a/src/dx9_overlay/Game/Game.cpp +++ b/src/dx9_overlay/Game/Game.cpp @@ -10,6 +10,8 @@ #include +#define BIND(T) PaketHandler[PipeMessages::T] = boost::bind(T, _1, _2); + CHook g_presentHook; CHook g_resetHook; @@ -47,65 +49,63 @@ void initGame() typedef std::map > MessagePaketHandler; MessagePaketHandler PaketHandler; - - PaketHandler[PipeMessages::TextCreate] = boost::bind(TextCreate, _1, _2); - PaketHandler[PipeMessages::TextDestroy] = boost::bind(TextDestroy, _1, _2); - PaketHandler[PipeMessages::TextSetShadow] = boost::bind(TextSetShadow, _1, _2); - PaketHandler[PipeMessages::TextSetShown] = boost::bind(TextSetShown, _1, _2); - PaketHandler[PipeMessages::TextSetColor] = boost::bind(TextSetColor, _1, _2); - PaketHandler[PipeMessages::TextSetPos] = boost::bind(TextSetPos, _1, _2); - PaketHandler[PipeMessages::TextSetString] = boost::bind(TextSetString, _1, _2); - PaketHandler[PipeMessages::TextUpdate] = boost::bind(TextUpdate, _1, _2); - - PaketHandler[PipeMessages::BoxCreate] = boost::bind(BoxCreate, _1, _2); - PaketHandler[PipeMessages::BoxDestroy] = boost::bind(BoxDestroy, _1, _2); - PaketHandler[PipeMessages::BoxSetShown] = boost::bind(BoxSetShown, _1, _2); - PaketHandler[PipeMessages::BoxSetBorder] = boost::bind(BoxSetBorder, _1, _2); - PaketHandler[PipeMessages::BoxSetBorderColor] = boost::bind(BoxSetBorderColor, _1, _2); - PaketHandler[PipeMessages::BoxSetColor] = boost::bind(BoxSetColor, _1, _2); - PaketHandler[PipeMessages::BoxSetHeight] = boost::bind(BoxSetHeight, _1, _2); - PaketHandler[PipeMessages::BoxSetPos] = boost::bind(BoxSetPos, _1, _2); - PaketHandler[PipeMessages::BoxSetWidth] = boost::bind(BoxSetWidth, _1, _2); - - PaketHandler[PipeMessages::LineCreate] = boost::bind(LineCreate, _1, _2); - PaketHandler[PipeMessages::LineDestroy] = boost::bind(LineDestroy, _1, _2); - PaketHandler[PipeMessages::LineSetShown] = boost::bind(LineSetShown, _1, _2); - PaketHandler[PipeMessages::LineSetColor] = boost::bind(LineSetColor, _1, _2); - PaketHandler[PipeMessages::LineSetWidth] = boost::bind(LineSetWidth, _1, _2); - PaketHandler[PipeMessages::LineSetPos] = boost::bind(LineSetPos, _1, _2); - - PaketHandler[PipeMessages::ImageCreate] = boost::bind(ImageCreate, _1, _2); - PaketHandler[PipeMessages::ImageDestroy] = boost::bind(ImageDestroy, _1, _2); - PaketHandler[PipeMessages::ImageSetShown] = boost::bind(ImageSetShown, _1, _2); - PaketHandler[PipeMessages::ImageSetAlign] = boost::bind(ImageSetAlign, _1, _2); - PaketHandler[PipeMessages::ImageSetPos] = boost::bind(ImageSetPos, _1, _2); - PaketHandler[PipeMessages::ImageSetRotation] = boost::bind(ImageSetRotation, _1, _2); - - PaketHandler[PipeMessages::DestroyAllVisual] = boost::bind(DestroyAllVisual, _1, _2); - PaketHandler[PipeMessages::ShowAllVisual] = boost::bind(ShowAllVisual, _1, _2); - PaketHandler[PipeMessages::HideAllVisual] = boost::bind(HideAllVisual, _1, _2); - - PaketHandler[PipeMessages::GetFrameRate] = boost::bind(GetFrameRate, _1, _2); - PaketHandler[PipeMessages::GetScreenSpecs] = boost::bind(GetScreenSpecs, _1, _2); - - new CNamedPipeServer("Overlay_Server", [&](CBitStream& bsIn, CBitStream& bsOut) + BIND(TextCreate); + BIND(TextDestroy); + BIND(TextSetShadow); + BIND(TextSetShown); + BIND(TextSetColor); + BIND(TextSetPos); + BIND(TextSetString); + BIND(TextUpdate); + + BIND(BoxCreate); + BIND(BoxDestroy); + BIND(BoxSetShown); + BIND(BoxSetBorder); + BIND(BoxSetBorderColor); + BIND(BoxSetColor); + BIND(BoxSetHeight); + BIND(BoxSetPos); + BIND(BoxSetWidth); + + BIND(LineCreate); + BIND(LineDestroy); + BIND(LineSetShown); + BIND(LineSetColor); + BIND(LineSetWidth); + BIND(LineSetPos); + + BIND(ImageCreate); + BIND(ImageDestroy); + BIND(ImageSetShown); + BIND(ImageSetAlign); + BIND(ImageSetPos); + BIND(ImageSetRotation); + + BIND(DestroyAllVisual); + BIND(ShowAllVisual); + BIND(HideAllVisual); + + BIND(GetFrameRate); + BIND(GetScreenSpecs); + + new CNamedPipeServer([&](CBitStream& bsIn, CBitStream& bsOut) { - BITSTREAM_READ(bsIn, short, eMessage); + BITSTREAM_READ(bsIn, PipeMessages, eMessage); try { - auto it = PaketHandler.find((PipeMessages)eMessage); + auto it = PaketHandler.find(eMessage); if (it == PaketHandler.end()) return; - if (!PaketHandler[(PipeMessages)eMessage]) + if (!PaketHandler[eMessage]) return; - PaketHandler[(PipeMessages)eMessage](bsIn, bsOut); + PaketHandler[eMessage](bsIn, bsOut); } catch (...) { - } }); diff --git a/src/dx9_overlay/Shared/Config.h b/src/dx9_overlay/Shared/Config.h new file mode 100644 index 0000000..4a73722 --- /dev/null +++ b/src/dx9_overlay/Shared/Config.h @@ -0,0 +1,3 @@ +#pragma once + +const char *const g_strPipeName = "Overlay_Server"; \ No newline at end of file diff --git a/src/dx9_overlay/Utils/NamedPipeClient.cpp b/src/dx9_overlay/Utils/NamedPipeClient.cpp index 962594d..3d8e1bc 100644 --- a/src/dx9_overlay/Utils/NamedPipeClient.cpp +++ b/src/dx9_overlay/Utils/NamedPipeClient.cpp @@ -2,16 +2,18 @@ #include "NamedPipeClient.h" #include "Bitstream.h" +#include + #include -CNamedPipeClient::CNamedPipeClient(const char *Pipe, CBitStream& bsIn, CBitStream& bsOut) : +CNamedPipeClient::CNamedPipeClient(CBitStream& bsIn, CBitStream& bsOut) : m_bSuccess(false) { char szData[BUFSIZE] = { 0 }; char szPipe[MAX_PATH + 1] = { 0 }; DWORD dwReaded; - sprintf(szPipe, "\\\\.\\pipe\\%s", Pipe); + sprintf(szPipe, "\\\\.\\pipe\\%s", g_strPipeName); if (CallNamedPipe(szPipe, (LPVOID)bsIn.GetData(), bsIn.GetNumberOfBytesUsed(), szData, sizeof(szData), &dwReaded, TIME_OUT)) { diff --git a/src/dx9_overlay/Utils/NamedPipeClient.h b/src/dx9_overlay/Utils/NamedPipeClient.h index 09da902..a7f7130 100644 --- a/src/dx9_overlay/Utils/NamedPipeClient.h +++ b/src/dx9_overlay/Utils/NamedPipeClient.h @@ -8,7 +8,7 @@ class CBitStream; class CNamedPipeClient { public: - CNamedPipeClient(const char *szPipe, CBitStream& bsIn, CBitStream& bsOut); + CNamedPipeClient(CBitStream& bsIn, CBitStream& bsOut); bool Success() const; private: diff --git a/src/dx9_overlay/Utils/NamedPipeServer.cpp b/src/dx9_overlay/Utils/NamedPipeServer.cpp index c1daccd..29b0b89 100644 --- a/src/dx9_overlay/Utils/NamedPipeServer.cpp +++ b/src/dx9_overlay/Utils/NamedPipeServer.cpp @@ -1,6 +1,8 @@ #include "NamedPipeServer.h" #include "Bitstream.h" +#include + #include #define CONNECTING_STATE 0 @@ -41,12 +43,12 @@ void CNamedPipeServer::DisconnectAndReconnect(DWORD dwIdx) m_Pipes[dwIdx].m_dwState = m_Pipes[dwIdx].m_fPendingIO ? CONNECTING_STATE : READING_STATE; } -CNamedPipeServer::CNamedPipeServer(const char *pipe, boost::function func) : m_cbCallback(func), m_thread(0) +CNamedPipeServer::CNamedPipeServer(boost::function func) : m_cbCallback(func), m_thread(0) { memset(m_szPipe, 0, sizeof(m_szPipe)); memset(m_Pipes, 0, sizeof(m_Pipes)); - sprintf_s(m_szPipe, "\\\\.\\pipe\\%s", pipe); + sprintf_s(m_szPipe, "\\\\.\\pipe\\%s", g_strPipeName); for (int i = 0; i < MAX_CLIENTS; i++) { diff --git a/src/dx9_overlay/Utils/NamedPipeServer.h b/src/dx9_overlay/Utils/NamedPipeServer.h index 3de7db0..0ebf623 100644 --- a/src/dx9_overlay/Utils/NamedPipeServer.h +++ b/src/dx9_overlay/Utils/NamedPipeServer.h @@ -13,7 +13,6 @@ class CBitStream; class CNamedPipeServer { -public: typedef struct { OVERLAPPED m_Overlapped; @@ -26,7 +25,8 @@ class CNamedPipeServer BOOL m_fPendingIO; } PIPEINSTANCE, *LPPIPEINSTANCE; - CNamedPipeServer(const char *pipe, boost::function func); +public: + CNamedPipeServer(boost::function func); ~CNamedPipeServer(); private: diff --git a/src/dx9_overlay/dx9_overlay.vcxproj b/src/dx9_overlay/dx9_overlay.vcxproj index c4858b3..5680244 100644 --- a/src/dx9_overlay/dx9_overlay.vcxproj +++ b/src/dx9_overlay/dx9_overlay.vcxproj @@ -117,6 +117,7 @@ + diff --git a/src/dx9_overlay/dx9_overlay.vcxproj.filters b/src/dx9_overlay/dx9_overlay.vcxproj.filters index b542a1e..94cafc3 100644 --- a/src/dx9_overlay/dx9_overlay.vcxproj.filters +++ b/src/dx9_overlay/dx9_overlay.vcxproj.filters @@ -61,12 +61,12 @@ {13d9c7aa-01e3-429c-b233-9963d359d701} - - {3b5d3b0a-16b2-4805-a0a8-4cf8445aec66} - {73d3675a-a6ac-4c93-ac87-a1d4d500dcc9} + + {3b5d3b0a-16b2-4805-a0a8-4cf8445aec66} + @@ -133,5 +133,8 @@ Utils + + Shared + \ No newline at end of file