mirror of
https://gitlab.com/Mr_Goldberg/goldberg_emulator.git
synced 2024-11-27 14:08:39 +01:00
Overlay & Hook cleanup.
This commit is contained in:
parent
44d583ee7d
commit
04847abeb7
6 changed files with 3 additions and 170 deletions
|
@ -93,30 +93,6 @@ void DX10_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain)
|
||||||
ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DirectX 10 Initialization functions
|
|
||||||
//HRESULT WINAPI DX10_Hook::MyD3D10CreateDevice(IDXGIAdapter* pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, UINT SDKVersion, ID3D10Device** ppDevice)
|
|
||||||
//{
|
|
||||||
// auto res = _D3D10CreateDevice(pAdapter, DriverType, Software, Flags, SDKVersion, ppDevice);
|
|
||||||
//
|
|
||||||
// if (SUCCEEDED(res))
|
|
||||||
// hook->hook_dx10(SDKVersion);
|
|
||||||
//
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//HRESULT WINAPI DX10_Hook::MyD3D10CreateDeviceAndSwapChain(IDXGIAdapter* pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, UINT SDKVersion,
|
|
||||||
// DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IDXGISwapChain** ppSwapChain, ID3D10Device** ppDevice)
|
|
||||||
//{
|
|
||||||
// auto res = hook->D3D10CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice);
|
|
||||||
//
|
|
||||||
// if (SUCCEEDED(res))
|
|
||||||
// hook->hook_dx10(SDKVersion);
|
|
||||||
//
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DX10_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
HRESULT STDMETHODCALLTYPE DX10_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
||||||
{
|
{
|
||||||
DX10_Hook::Inst()->prepareForOverlay(_this);
|
DX10_Hook::Inst()->prepareForOverlay(_this);
|
||||||
|
@ -145,18 +121,6 @@ DX10_Hook::DX10_Hook():
|
||||||
ResizeTarget(nullptr)
|
ResizeTarget(nullptr)
|
||||||
{
|
{
|
||||||
_library = LoadLibrary(DLL_NAME);
|
_library = LoadLibrary(DLL_NAME);
|
||||||
|
|
||||||
// Hook to D3D10CreateDevice and D3D10CreateDeviceAndSwapChain so we know when it gets called.
|
|
||||||
// If its called, then DX10 will be used to render the overlay.
|
|
||||||
//_D3D10CreateDevice = (decltype(_D3D10CreateDevice))GetProcAddress(_dll, "D3D10CreateDevice");
|
|
||||||
//D3D10CreateDeviceAndSwapChain = (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D10CreateDeviceAndSwapChain");
|
|
||||||
//
|
|
||||||
//BeginHook();
|
|
||||||
//HookFuncs(
|
|
||||||
// //std::make_pair<void**, void*>(&(PVOID&)_D3D10CreateDevice, &DX10_Hook::MyD3D10CreateDevice),
|
|
||||||
// std::make_pair<void**, void*>(&(PVOID&)D3D10CreateDeviceAndSwapChain, &DX10_Hook::MyD3D10CreateDeviceAndSwapChain)
|
|
||||||
//);
|
|
||||||
//EndHook();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DX10_Hook::~DX10_Hook()
|
DX10_Hook::~DX10_Hook()
|
||||||
|
@ -167,7 +131,6 @@ DX10_Hook::~DX10_Hook()
|
||||||
{
|
{
|
||||||
mainRenderTargetView->Release();
|
mainRenderTargetView->Release();
|
||||||
|
|
||||||
//ImGui_ImplDX10_Shutdown();
|
|
||||||
ImGui_ImplDX10_InvalidateDeviceObjects();
|
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
|
|
@ -105,34 +105,6 @@ void DX11_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain)
|
||||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DirectX 11 Initialization functions
|
|
||||||
//HRESULT WINAPI DX11_Hook::MyD3D11CreateDevice(__in_opt IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags,
|
|
||||||
// __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, __out_opt ID3D11Device** ppDevice,
|
|
||||||
// __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, __out_opt ID3D11DeviceContext** ppImmediateContext)
|
|
||||||
//{
|
|
||||||
// auto res = D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext);
|
|
||||||
//
|
|
||||||
// if (SUCCEEDED(res))
|
|
||||||
// hook->hook_dx11(SDKVersion);
|
|
||||||
//
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//HRESULT WINAPI DX11_Hook::MyD3D11CreateDeviceAndSwapChain(__in_opt IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags,
|
|
||||||
// __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion,
|
|
||||||
// __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, __out_opt IDXGISwapChain** ppSwapChain, __out_opt ID3D11Device** ppDevice,
|
|
||||||
// __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, __out_opt ID3D11DeviceContext** ppImmediateContext)
|
|
||||||
//{
|
|
||||||
// auto res = hook->D3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext);
|
|
||||||
//
|
|
||||||
// if (SUCCEEDED(res))
|
|
||||||
// hook->hook_dx11(SDKVersion);
|
|
||||||
//
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DX11_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
HRESULT STDMETHODCALLTYPE DX11_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
||||||
{
|
{
|
||||||
DX11_Hook::Inst()->prepareForOverlay(_this);
|
DX11_Hook::Inst()->prepareForOverlay(_this);
|
||||||
|
@ -162,18 +134,6 @@ DX11_Hook::DX11_Hook():
|
||||||
ResizeTarget(nullptr)
|
ResizeTarget(nullptr)
|
||||||
{
|
{
|
||||||
_library = LoadLibrary(DLL_NAME);
|
_library = LoadLibrary(DLL_NAME);
|
||||||
|
|
||||||
// Hook to D3D11CreateDevice and D3D11CreateDeviceAndSwapChain so we know when it gets called.
|
|
||||||
// If its called, then DX11 will be used to render the overlay.
|
|
||||||
//D3D11CreateDevice = (decltype(D3D11CreateDevice))GetProcAddress(_dll, "D3D11CreateDevice");
|
|
||||||
//D3D11CreateDeviceAndSwapChain = (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(_dll, "D3D11CreateDeviceAndSwapChain");
|
|
||||||
//
|
|
||||||
//BeginHook();
|
|
||||||
//HookFuncs(
|
|
||||||
// //std::make_pair<void**, void*>(&(PVOID&)D3D11CreateDevice, &DX11_Hook::MyD3D11CreateDevice),
|
|
||||||
// std::make_pair<void**, void*>(&(PVOID&)D3D11CreateDeviceAndSwapChain, &DX11_Hook::MyD3D11CreateDeviceAndSwapChain)
|
|
||||||
//);
|
|
||||||
//EndHook();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DX11_Hook::~DX11_Hook()
|
DX11_Hook::~DX11_Hook()
|
||||||
|
@ -185,7 +145,6 @@ DX11_Hook::~DX11_Hook()
|
||||||
mainRenderTargetView->Release();
|
mainRenderTargetView->Release();
|
||||||
pContext->Release();
|
pContext->Release();
|
||||||
|
|
||||||
//ImGui_ImplDX11_Shutdown();
|
|
||||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
|
|
@ -94,23 +94,6 @@ void DX12_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DirectX 12 Initialization functions
|
|
||||||
//HRESULT WINAPI DX12_Hook::MyD3D12CreateDevice(
|
|
||||||
// _In_opt_ IUnknown* pAdapter,
|
|
||||||
// D3D_FEATURE_LEVEL MinimumFeatureLevel,
|
|
||||||
// _In_ REFIID riid, // Expected: ID3D12Device
|
|
||||||
// _COM_Outptr_opt_ void** ppDevice)
|
|
||||||
//{
|
|
||||||
// auto res = hook->D3D12CreateDevice(pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
|
||||||
//
|
|
||||||
// if (SUCCEEDED(res))
|
|
||||||
// hook->hook_dx12(MinimumFeatureLevel);
|
|
||||||
//
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DX12_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
HRESULT STDMETHODCALLTYPE DX12_Hook::MyPresent(IDXGISwapChain *_this, UINT SyncInterval, UINT Flags)
|
||||||
{
|
{
|
||||||
DX12_Hook::Inst()->prepareForOverlay(_this);
|
DX12_Hook::Inst()->prepareForOverlay(_this);
|
||||||
|
@ -185,16 +168,6 @@ DX12_Hook::DX12_Hook():
|
||||||
_library = LoadLibrary(DLL_NAME);
|
_library = LoadLibrary(DLL_NAME);
|
||||||
|
|
||||||
PRINT_DEBUG("DX12 support is experimental, don't complain if it doesn't work as expected.\n");
|
PRINT_DEBUG("DX12 support is experimental, don't complain if it doesn't work as expected.\n");
|
||||||
|
|
||||||
// Hook to D3D12CreateDevice and D3D12CreateDeviceAndSwapChain so we know when it gets called.
|
|
||||||
// If its called, then DX12 will be used to render the overlay.
|
|
||||||
//D3D12CreateDevice = (decltype(D3D12CreateDevice))GetProcAddress(_dll, "D3D12CreateDevice");
|
|
||||||
//
|
|
||||||
//BeginHook();
|
|
||||||
//HookFuncs(
|
|
||||||
// std::make_pair<void**, void*>(&(PVOID&)D3D12CreateDevice, &DX12_Hook::MyD3D12CreateDevice)
|
|
||||||
//);
|
|
||||||
//EndHook();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DX12_Hook::~DX12_Hook()
|
DX12_Hook::~DX12_Hook()
|
||||||
|
@ -203,7 +176,6 @@ DX12_Hook::~DX12_Hook()
|
||||||
|
|
||||||
if (initialized)
|
if (initialized)
|
||||||
{
|
{
|
||||||
//ImGui_ImplDX12_Shutdown();
|
|
||||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
|
|
@ -94,29 +94,6 @@ void DX9_Hook::prepareForOverlay(IDirect3DDevice9 *pDevice)
|
||||||
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DirectX 9 Initialization functions
|
|
||||||
//IDirect3D9* DX9_Hook::MyDirect3DCreate9(UINT SDKVersion)
|
|
||||||
//{
|
|
||||||
// auto res = hook->Direct3DCreate9(SDKVersion);
|
|
||||||
//
|
|
||||||
// if( res != nullptr )
|
|
||||||
// hook->hook_dx9(SDKVersion);
|
|
||||||
//
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//HRESULT DX9_Hook::MyDirect3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppDevice)
|
|
||||||
//{
|
|
||||||
// auto res = hook->Direct3DCreate9Ex(SDKVersion, ppDevice);
|
|
||||||
//
|
|
||||||
// if (SUCCEEDED(res))
|
|
||||||
// hook->hook_dx9(SDKVersion);
|
|
||||||
//
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DX9_Hook::MyReset(IDirect3DDevice9* _this, D3DPRESENT_PARAMETERS* pPresentationParameters)
|
HRESULT STDMETHODCALLTYPE DX9_Hook::MyReset(IDirect3DDevice9* _this, D3DPRESENT_PARAMETERS* pPresentationParameters)
|
||||||
{
|
{
|
||||||
DX9_Hook::Inst()->resetRenderState();
|
DX9_Hook::Inst()->resetRenderState();
|
||||||
|
@ -154,28 +131,14 @@ DX9_Hook::DX9_Hook():
|
||||||
Reset(nullptr)
|
Reset(nullptr)
|
||||||
{
|
{
|
||||||
_library = LoadLibrary(DLL_NAME);
|
_library = LoadLibrary(DLL_NAME);
|
||||||
// Hook to Direct3DCreate9 and Direct3DCreate9Ex so we know when it gets called.
|
|
||||||
// If its called, then DX9 will be used to render the overlay.
|
|
||||||
//Direct3DCreate9 = (decltype(Direct3DCreate9))GetProcAddress(_dll, "Direct3DCreate9");
|
|
||||||
//Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(_dll, "Direct3DCreate9Ex");
|
|
||||||
//
|
|
||||||
//BeginHook();
|
|
||||||
//HookFuncs(
|
|
||||||
// std::make_pair<void**, void*>(&(PVOID&)Direct3DCreate9, &DX9_Hook::MyDirect3DCreate9),
|
|
||||||
// std::make_pair<void**, void*>(&(PVOID&)Direct3DCreate9Ex, &DX9_Hook::MyDirect3DCreate9Ex)
|
|
||||||
//);
|
|
||||||
//EndHook();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DX9_Hook::~DX9_Hook()
|
DX9_Hook::~DX9_Hook()
|
||||||
{
|
{
|
||||||
PRINT_DEBUG("DX9 Hook removed\n");
|
PRINT_DEBUG("DX9 Hook removed\n");
|
||||||
|
|
||||||
//resetRenderState();
|
|
||||||
if (initialized)
|
if (initialized)
|
||||||
{
|
{
|
||||||
//ImGui_ImplDX9_Shutdown(); This makes some games hang when Releasing the D3D9 device (pDevice->Release())
|
|
||||||
// maybe because D3D is already shut down when we try to free the device?
|
|
||||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,16 +98,6 @@ void OpenGL_Hook::prepareForOverlay(HDC hDC)
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// OpenGL Initialization functions
|
|
||||||
//BOOL WINAPI OpenGL_Hook::MywglMakeCurrent(HDC hDC, HGLRC hGLRC)
|
|
||||||
//{
|
|
||||||
// auto res = hook->wglMakeCurrent(hDC, hGLRC);
|
|
||||||
// hook->hook_ogl();
|
|
||||||
// return res;
|
|
||||||
//}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
BOOL WINAPI OpenGL_Hook::MywglSwapBuffers(HDC hDC)
|
BOOL WINAPI OpenGL_Hook::MywglSwapBuffers(HDC hDC)
|
||||||
{
|
{
|
||||||
OpenGL_Hook::Inst()->prepareForOverlay(hDC);
|
OpenGL_Hook::Inst()->prepareForOverlay(hDC);
|
||||||
|
@ -120,16 +110,6 @@ OpenGL_Hook::OpenGL_Hook():
|
||||||
wglSwapBuffers(nullptr)
|
wglSwapBuffers(nullptr)
|
||||||
{
|
{
|
||||||
_library = LoadLibrary(DLL_NAME);
|
_library = LoadLibrary(DLL_NAME);
|
||||||
// Hook to wglMakeCurrent so we know when it gets called.
|
|
||||||
// If its called, then OpenGL will be used to render the overlay.
|
|
||||||
//wglMakeCurrent = (decltype(wglMakeCurrent))GetProcAddress(_dll, "wglMakeCurrent");
|
|
||||||
//wglSwapBuffers = (decltype(wglSwapBuffers))GetProcAddress(_dll, "wglSwapBuffers");
|
|
||||||
//
|
|
||||||
//BeginHook();
|
|
||||||
//HookFuncs(
|
|
||||||
// std::make_pair<void**, void*>(&(PVOID&)wglMakeCurrent, &OpenGL_Hook::MywglMakeCurrent)
|
|
||||||
//);
|
|
||||||
//EndHook();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGL_Hook::~OpenGL_Hook()
|
OpenGL_Hook::~OpenGL_Hook()
|
||||||
|
|
|
@ -182,7 +182,7 @@ void Steam_Overlay::SetLobbyInvite(Friend friendId, uint64 lobbyId)
|
||||||
if (!(frd.window_state & window_state_show))
|
if (!(frd.window_state & window_state_show))
|
||||||
{
|
{
|
||||||
frd.window_state |= window_state_need_attention;
|
frd.window_state |= window_state_need_attention;
|
||||||
PlaySound((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY);
|
// TODO: Push a notification
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ void Steam_Overlay::SetRichInvite(Friend friendId, const char* connect_str)
|
||||||
if (!(frd.window_state & window_state_show))
|
if (!(frd.window_state & window_state_show))
|
||||||
{
|
{
|
||||||
frd.window_state |= window_state_need_attention;
|
frd.window_state |= window_state_need_attention;
|
||||||
PlaySound((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY);
|
// TODO: Push a notification
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,6 +298,7 @@ void Steam_Overlay::BuildFriendWindow(Friend const& frd, friend_window_state& st
|
||||||
{
|
{
|
||||||
if (state.window_state & window_state_need_attention && ImGui::IsWindowFocused())
|
if (state.window_state & window_state_need_attention && ImGui::IsWindowFocused())
|
||||||
{
|
{
|
||||||
|
PlaySound((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY);
|
||||||
state.window_state &= ~window_state_need_attention;
|
state.window_state &= ~window_state_need_attention;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,10 +422,6 @@ void Steam_Overlay::OverlayProc( int width, int height )
|
||||||
{
|
{
|
||||||
ImGui::PushID(i.first.id());
|
ImGui::PushID(i.first.id());
|
||||||
|
|
||||||
/* TODO: Do something with this to notify the user something happened with this friend (invite or chat)
|
|
||||||
* i.second.window_state & window_state_need_attention
|
|
||||||
*/
|
|
||||||
|
|
||||||
ImGui::Selectable(i.first.name().c_str(), false, ImGuiSelectableFlags_AllowDoubleClick);
|
ImGui::Selectable(i.first.name().c_str(), false, ImGuiSelectableFlags_AllowDoubleClick);
|
||||||
BuildContextMenu(i.first, i.second);
|
BuildContextMenu(i.first, i.second);
|
||||||
if (ImGui::IsItemClicked() && ImGui::IsMouseDoubleClicked(0))
|
if (ImGui::IsItemClicked() && ImGui::IsMouseDoubleClicked(0))
|
||||||
|
@ -459,7 +456,6 @@ void Steam_Overlay::Callback(Common_Message *msg)
|
||||||
if (!(friend_info->second.window_state & window_state_show))
|
if (!(friend_info->second.window_state & window_state_show))
|
||||||
{
|
{
|
||||||
friend_info->second.window_state |= window_state_need_attention;
|
friend_info->second.window_state |= window_state_need_attention;
|
||||||
PlaySound((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue