Skip to content

Commit

Permalink
fix #25
Browse files Browse the repository at this point in the history
  • Loading branch information
sunghwan2789 committed Dec 20, 2015
1 parent 9aa7114 commit 347256c
Show file tree
Hide file tree
Showing 9 changed files with 1,217 additions and 53 deletions.
10 changes: 7 additions & 3 deletions Server/Hooker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
#include <Windows.h>
#include <cstring>

template<typename F> Hooker<F>::Hooker(const char *moduleName, const char *funcName)
template<typename F> Hooker<F>::Hooker(const char *moduleName, const char *functionName, F hkFunction = nullptr)
{
InitializeCriticalSection(&this->hMutex);
this->Hooked = false;

this->pFunction = (F) GetProcAddress(GetModuleHandle(moduleName), funcName);
this->pFunction = (F) GetProcAddress(GetModuleHandle(moduleName), functionName);
this->hkFunction = hkFunction;
}

template<typename F> Hooker<F>::~Hooker()
Expand All @@ -26,7 +27,7 @@ template<typename F> void Hooker<F>::Set(F hkFunction)

template<typename F> void Hooker<F>::Hook()
{
if (this->Hooked)
if (this->Hooked && this->hkFunction)
{
return;
}
Expand Down Expand Up @@ -74,3 +75,6 @@ template<typename F> void Hooker<F>::LeaveCS()

// explicit instantiation
template class Hooker<tReadFile>;
template class Hooker<tBASS_ChannelPlay>;
template class Hooker<tBASS_ChannelSetPosition>;
template class Hooker<tBASS_ChannelSetAttribute>;
10 changes: 9 additions & 1 deletion Server/Hooker.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <Windows.h>
#include "bass.h"

const BYTE szOpcode = 1 + sizeof(DWORD);
const BYTE asmJmp = 0xE9;
Expand All @@ -16,7 +17,7 @@ template<typename F> class Hooker
public:
F pFunction;

Hooker(const char *, const char *);
Hooker(const char *, const char *, F = nullptr);
~Hooker();

void Set(F);
Expand All @@ -29,3 +30,10 @@ template<typename F> class Hooker
};

typedef BOOL (WINAPI *tReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
BOOL WINAPI hkReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
typedef BOOL (BASSDEF(*tBASS_ChannelPlay))(DWORD, BOOL);
BOOL BASSDEF(hkBASS_ChannelPlay)(DWORD, BOOL);
typedef BOOL (BASSDEF(*tBASS_ChannelSetPosition))(DWORD, QWORD, DWORD);
BOOL BASSDEF(hkBASS_ChannelSetPosition)(DWORD, QWORD, DWORD);
typedef BOOL (BASSDEF(*tBASS_ChannelSetAttribute))(DWORD, DWORD, float);
BOOL BASSDEF(hkBASS_ChannelSetAttribute)(DWORD, DWORD, float);
192 changes: 150 additions & 42 deletions Server/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,31 @@
#include <Windows.h>
#include <Shlwapi.h>
#include <unordered_map>
#include <mutex>
#include <cstring>
#include <string>
#include <utility>
#include "bass.h"
#include "ConcurrentQueue.h"
#include "Hooker.h"
using namespace std;

#define BUF_SIZE MAX_PATH * 3
#define OSU_BASS_ATTRIB_MUSIC_SPEED 0x10000

long long CurrentTime()
inline long long CurrentTime()
{
long long t;
GetSystemTimeAsFileTime((LPFILETIME) &t);
return t;
}


ConcurrentQueue<string> MessageQueue;

HANDLE hPipeThread;
HANDLE hPipe;
volatile bool bCancelPipeThread;
volatile bool bPipeConnected;

ConcurrentQueue<string> MessageQueue;

DWORD WINAPI PipeThread(LPVOID lParam)
{
hPipe = CreateNamedPipe("\\\\.\\pipe\\osu!Lyrics", PIPE_ACCESS_OUTBOUND,
Expand Down Expand Up @@ -65,17 +69,17 @@ DWORD WINAPI PipeThread(LPVOID lParam)
}


Hooker<tReadFile> hkrReadFile("kernel32.dll", "ReadFile");
pair<string, string> Playing;
unordered_map<string, string> AudioInfo;

// osu!에서 ReadFile을 호출하면 정보를 빼내서 osu!Lyrics로 보냄
Hooker<tReadFile> hkrReadFile("kernel32.dll", "ReadFile", hkReadFile);
BOOL WINAPI hkReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
{
long long calledAt = CurrentTime();
BOOL result;

hkrReadFile.EnterCS();
hkrReadFile.Unhook();
BOOL result = hkrReadFile.pFunction(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
result = hkrReadFile.pFunction(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
hkrReadFile.Hook();
hkrReadFile.LeaveCS();
if (!result)
Expand All @@ -93,72 +97,176 @@ BOOL WINAPI hkReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead
{
// strtok�� �ҽ��� �����ϹǷ� �ϴ� ���
char *buffer = strdup((char *) lpBuffer);
char *line = strtok(buffer, "\n");
while (line != NULL)
for (char *line = strtok(buffer, "\n"); line != NULL; line = strtok(NULL, "\n"))
{
// ��Ʈ���� ���� ���� ��� ���
if (strnicmp(line, "AudioFilename:", 14) == 0)
if (strnicmp(line, "AudioFilename:", 14) != 0)
{
char *beatmapDir = strdup(path);
PathRemoveFileSpec(beatmapDir);
continue;
}

char audioPath[MAX_PATH];
char *beatmapDir = strdup(path);
PathRemoveFileSpec(beatmapDir);

// get value & trim
int i = 14;
for (; line[i] == ' '; i++);
buffer[0] = '\0';
strncat(buffer, &line[i], strlen(line) - i - 1);
PathCombine(audioPath, beatmapDir, buffer);
char audioPath[MAX_PATH];

// 검색할 때 대소문자 구분하므로 제대로 된 파일 경로 얻기
WIN32_FIND_DATA fdata;
FindClose(FindFirstFile(audioPath, &fdata));
PathRemoveFileSpec(audioPath);
PathCombine(audioPath, audioPath, fdata.cFileName);
// get value & trim
int i = 14;
for (; line[i] == ' '; i++);
buffer[0] = NULL;
strncat(buffer, &line[i], strlen(line) - i - 1);
PathCombine(audioPath, beatmapDir, buffer);

AudioInfo.insert(make_pair(string(audioPath), string(path)));
// �˻��� �� ��ҹ��� �����ϹǷ� ����� �� ���� ��� ���
WIN32_FIND_DATA fdata;
FindClose(FindFirstFile(audioPath, &fdata));
PathRemoveFileSpec(audioPath);
PathCombine(audioPath, audioPath, fdata.cFileName);

free(beatmapDir);
break;
}
line = strtok(NULL, "\n");
AudioInfo.emplace(audioPath, path);

free(beatmapDir);
break;
}
free(buffer);
}
// 파이프 연결이 끊겼으면 유저가 가사를 보고 싶지 않다는 것:
// osu!가 게임 플레이에만 집중하게 하자... 자원 낭비 금지
else if (bPipeConnected)
else
{
// [ audioPath, beatmapPath ]
unordered_map<string, string>::iterator pair = AudioInfo.find(string(path));
unordered_map<string, string>::iterator pair = AudioInfo.find(path);
if (pair != AudioInfo.end())
{
char message[BUF_SIZE];
sprintf(message, "%llx|%s|%lx|%s\n", calledAt, &path[4], seekPosition, &pair->second[4]);
MessageQueue.Push(string(message));
Playing = *pair;
}
}

return TRUE;
}


HANDLE hPipeThread;
Hooker<tBASS_ChannelPlay> hkrPlay("bass.dll", "BASS_ChannelPlay", hkBASS_ChannelPlay);
BOOL BASSDEF(hkBASS_ChannelPlay)(DWORD handle, BOOL restart)
{
BOOL result;

hkrPlay.EnterCS();
hkrPlay.Unhook();
result = hkrPlay.pFunction(handle, restart);
hkrPlay.Hook();
hkrPlay.LeaveCS();

This comment has been minimized.

Copy link
@sunghwan2789

sunghwan2789 Dec 20, 2015

Author Owner

이 다섯 줄을 한 줄로 줄이고싶다 ㅋㅋ

if (!result)
{
return FALSE;
}

BASS_CHANNELINFO info;
BASS_ChannelGetInfo(handle, &info);
if (!(info.ctype & BASS_CTYPE_STREAM))
{
return TRUE;
}

char message[BUF_SIZE];
long long calledAt = CurrentTime();
double currentTime = BASS_ChannelBytes2Seconds(handle, BASS_ChannelGetPosition(handle, BASS_POS_BYTE));
float playbackRate; BASS_ChannelGetAttribute(handle, OSU_BASS_ATTRIB_MUSIC_SPEED, &playbackRate);
sprintf(message, "%llx|%s|%lf|%f|%s\n", calledAt, &Playing.first[4], currentTime, playbackRate, &Playing.second[4]);
MessageQueue.Push(message);

return TRUE;
}

Hooker<tBASS_ChannelSetPosition> hkrSetPos("bass.dll", "BASS_ChannelSetPosition", hkBASS_ChannelSetPosition);
BOOL BASSDEF(hkBASS_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode)
{
BOOL result;

hkrSetPos.EnterCS();
hkrSetPos.Unhook();
result = hkrSetPos.pFunction(handle, pos, mode);
hkrSetPos.Hook();
hkrSetPos.LeaveCS();
if (!result)
{
return FALSE;
}

BASS_CHANNELINFO info;
BASS_ChannelGetInfo(handle, &info);
if (!(info.ctype & BASS_CTYPE_STREAM))
{
return TRUE;
}

char message[BUF_SIZE];
long long calledAt = CurrentTime();
double currentTime = BASS_ChannelBytes2Seconds(handle, pos);
float playbackRate; BASS_ChannelGetAttribute(handle, OSU_BASS_ATTRIB_MUSIC_SPEED, &playbackRate);
sprintf(message, "%llx|%s|%lf|%f|%s\n", calledAt, &Playing.first[4], currentTime, playbackRate, &Playing.second[4]);
MessageQueue.Push(message);

return TRUE;
}

Hooker<tBASS_ChannelSetAttribute> hkrSetAttr("bass.dll", "BASS_ChannelSetAttribute", hkBASS_ChannelSetAttribute);
BOOL BASSDEF(hkBASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value)
{
BOOL result;

hkrSetAttr.EnterCS();
hkrSetAttr.Unhook();
result = hkrSetAttr.pFunction(handle, attrib, value);
hkrSetAttr.Hook();
hkrSetAttr.LeaveCS();
if (!result)
{
return FALSE;
}

BASS_CHANNELINFO info;
BASS_ChannelGetInfo(handle, &info);
if (!(info.ctype & BASS_CTYPE_STREAM) || attrib != OSU_BASS_ATTRIB_MUSIC_SPEED)
{
return TRUE;
}

char message[BUF_SIZE];
long long calledAt = CurrentTime();
double currentTime = BASS_ChannelBytes2Seconds(handle, BASS_ChannelGetPosition(handle, BASS_POS_BYTE));
sprintf(message, "%llx|%s|%lf|%f|%s\n", calledAt, &Playing.first[4], currentTime, value, &Playing.second[4]);
MessageQueue.Push(message);

return TRUE;
}


BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
hPipeThread = CreateThread(NULL, 0, PipeThread, NULL, 0, NULL);

hkrReadFile.Set(hkReadFile);
hkrPlay.Hook();
hkrSetAttr.Hook();
hkrSetPos.Hook();

hkrReadFile.Hook();
}
else if (fdwReason == DLL_PROCESS_DETACH)
{
// hkrReadFile.EnterCS();
hkrReadFile.EnterCS();
hkrReadFile.Unhook();
// hkrReadFile.LeaveCS();
hkrReadFile.LeaveCS();

hkrSetAttr.EnterCS();
hkrSetAttr.Unhook();
hkrSetAttr.LeaveCS();
hkrSetPos.EnterCS();
hkrSetPos.Unhook();
hkrSetPos.LeaveCS();
hkrPlay.EnterCS();
hkrPlay.Unhook();
hkrPlay.LeaveCS();

bCancelPipeThread = true;
DisconnectNamedPipe(hPipe);
Expand Down
Binary file modified Server/Resource.rc
Binary file not shown.
4 changes: 4 additions & 0 deletions Server/Server.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,17 @@
<ClCompile Include="Program.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="bass.h" />
<ClInclude Include="ConcurrentQueue.h" />
<ClInclude Include="Hooker.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resource.rc" />
</ItemGroup>
<ItemGroup>
<Library Include="bass.lib" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
Expand Down
Loading

0 comments on commit 347256c

Please sign in to comment.