Full Unicode patch with RTL Support & BiDi logic.

This commit is well documented, so no need to tell you my life story.

Full Unicode patch with RTL Support & BiDi logic.

Removed the legacy codePage, normalised to UTF8 (65001).

It also comes with:

CTRL + A : select text (highlighted)
CTRL + C : copy
CTRL + V : paste
CTRL + X : cut
CTRL + Y : redo
CTRL + Z : undo
This commit is contained in:
rtw1x1
2025-12-26 12:32:43 +00:00
parent d37607baa1
commit a955c50744
86 changed files with 4076 additions and 3839 deletions

View File

@@ -48,7 +48,6 @@ class IAbstractApplication : public TAbstractSingleton<IAbstractApplication>
virtual void RunIMETabEvent() = 0;
virtual void RunIMEReturnEvent() = 0;
virtual void RunIMEChangeCodePage() = 0;
virtual void RunIMEOpenCandidateListEvent() = 0;
virtual void RunIMECloseCandidateListEvent() = 0;
virtual void RunIMEOpenReadingWndEvent() = 0;

View File

@@ -35,18 +35,8 @@ bool CAccountConnector::Connect(const char * c_szAddr, int iPort, const char * c
m_strAddr = c_szAddr;
m_iPort = iPort;
__OfflineState_Set();
// CHINA_CRYPT_KEY
if (LocaleService_IsYMIR())
{
}
else
{
__BuildClientKey_20050304Myevan();
}
// END_OF_CHINA_CRYPT_KEY
__BuildClientKey_20050304Myevan();
return CNetworkStream::Connect(c_szAccountAddr, iAccountPort);
}
@@ -173,7 +163,7 @@ bool CAccountConnector::__AuthState_RecvPhase()
else if (kPacketPhase.phase == PHASE_AUTH)
{
#ifndef _IMPROVED_PACKET_ENCRYPTION_
const char* key = LocaleService_GetSecurityKey();
const char* key = GetSecurityKey();
SetSecurityMode(true, key);
#endif

View File

@@ -2,7 +2,6 @@
#include "GuildMarkDownloader.h"
#include "PythonCharacterManager.h"
#include "Packet.h"
#include "Test.h"
// MARK_BUG_FIX
struct SMarkIndex
@@ -258,7 +257,7 @@ bool CGuildMarkDownloader::__LoginState_RecvPhase()
if (kPacketPhase.phase == PHASE_LOGIN)
{
#ifndef _IMPROVED_PACKET_ENCRYPTION_
const char* key = LocaleService_GetSecurityKey();
const char* key = GetSecurityKey();
SetSecurityMode(true, key);
#endif
@@ -287,7 +286,7 @@ bool CGuildMarkDownloader::__LoginState_RecvPhase()
}
return true;
}
}
// MARK_BUG_FIX
bool CGuildMarkDownloader::__SendMarkIDXList()

View File

@@ -1,7 +1,6 @@
#include "StdAfx.h"
#include "GuildMarkUploader.h"
#include "Packet.h"
#include "Test.h"
#include "stb_image.h"
#include "stb_image_write.h"
@@ -332,7 +331,7 @@ bool CGuildMarkUploader::__LoginState_RecvPhase()
if (kPacketPhase.phase==PHASE_LOGIN)
{
#ifndef _IMPROVED_PACKET_ENCRYPTION_
const char* key = LocaleService_GetSecurityKey();
const char* key = GetSecurityKey();
SetSecurityMode(true, key);
#endif

View File

@@ -28,15 +28,14 @@ void CInsultChecker::AppendInsult(const std::string& c_rstInsult)
bool CInsultChecker::__GetInsultLength(const char* c_szWord, UINT* puInsultLen)
{
std::list<std::string>::iterator i;
for (i=m_kList_stInsult.begin(); i!=m_kList_stInsult.end(); ++i)
for (auto i = m_kList_stInsult.begin(); i != m_kList_stInsult.end(); ++i)
{
std::string& rstInsult=*i;
auto rstInsult = *i;
int ret = StringCompareCI(c_szWord, rstInsult.c_str(), rstInsult.length());
int ret=LocaleService_StringCompareCI(c_szWord, rstInsult.c_str(), rstInsult.length());
if (0==ret)
if (0 == ret)
{
*puInsultLen=rstInsult.length();
*puInsultLen = rstInsult.length();
return true;
}
}
@@ -64,10 +63,7 @@ void CInsultChecker::FilterInsult(char* szLine, UINT uLineLen)
}
else
{
if ( LocaleService_IsLeadByte( bChr ) )
uPos += 2;
else
uPos++;
uPos++;
}
}
}

View File

@@ -3,418 +3,129 @@
#include "PythonApplication.h"
#include "resource.h"
#include "EterBase/CRC32.h"
#include "EterLocale/Japanese.h"
#include <windowsx.h>
const char* LSS_YMIR = "YMIR";
const char* LSS_JAPAN = "JAPAN";
const char* LSS_ENGLISH = "ENGLISH";
const char* LSS_HONGKONG = "HONGKONG";
const char* LSS_TAIWAN = "TAIWAN";
const char* LSS_NEWCIBN = "NEWCIBN";
const char* LSS_EUROPE = "EUROPE";
const char* LSS_GLOBAL = "GLOBAL";
static bool IS_CHEONMA = false;
#ifndef LSS_SECURITY_KEY
#define LSS_SECURITY_KEY "testtesttesttest"
#define LSS_SECURITY_KEY "testtesttesttest"
#endif
std::string __SECURITY_KEY_STRING__ = LSS_SECURITY_KEY;
char MULTI_LOCALE_SERVICE[256] = "YMIR";
char MULTI_LOCALE_PATH[256] = "locale/ymir";
char MULTI_LOCALE_NAME[256] = "ymir";
int MULTI_LOCALE_CODE = 949;
int MULTI_LOCALE_REPORT_PORT = 10000;
char MULTI_LOCALE_PATH_COMMON[256] = "locale/common";
char MULTI_LOCALE_PATH[256] = "locale/en";
char MULTI_LOCALE_NAME[256] = "en";
void LocaleService_LoadConfig(const char* fileName)
void LoadConfig(const char* fileName)
{
NANOBEGIN
FILE* fp = fopen(fileName, "rt");
strncpy_s(MULTI_LOCALE_NAME, "en", _TRUNCATE);
_snprintf_s(MULTI_LOCALE_PATH, _countof(MULTI_LOCALE_PATH), _TRUNCATE, "locale/%s", MULTI_LOCALE_NAME);
if (fp)
{
char line[256];
char name[256];
int code;
int id;
if (fgets(line, sizeof(line)-1, fp))
auto fp = fopen(fileName, "rt");
if (!fp)
return;
char line[256] = {};
if (fgets(line, sizeof(line) - 1, fp))
{
char name[256] = {};
if (sscanf(line, "%255s", name) == 1)
{
line[sizeof(line)-1] = '\0';
sscanf(line, "%d %d %s", &id, &code, name);
MULTI_LOCALE_REPORT_PORT = id;
MULTI_LOCALE_CODE = code;
strcpy(MULTI_LOCALE_NAME, name);
sprintf(MULTI_LOCALE_PATH, "locale/%s", MULTI_LOCALE_NAME);
}
fclose(fp);
strncpy_s(MULTI_LOCALE_NAME, name, _TRUNCATE);
_snprintf_s(MULTI_LOCALE_PATH, _countof(MULTI_LOCALE_PATH), _TRUNCATE, "locale/%s", MULTI_LOCALE_NAME);
}
}
NANOEND
fclose(fp);
}
unsigned LocaleService_GetLastExp(int level)
unsigned GetGuildLastExp(int level)
{
static const int GUILD_LEVEL_MAX = 20;
if (LocaleService_IsCHEONMA())
static DWORD GUILD_EXP_LIST[GUILD_LEVEL_MAX + 1] =
{
static DWORD CHEONMA_GUILDEXP_LIST[GUILD_LEVEL_MAX+1] =
{
0, // 0
15000ul, // 1
45000ul, // 2
90000ul, // 3
160000ul, // 4
235000ul, // 5
325000ul, // 6
430000ul, // 7
550000ul, // 8
685000ul, // 9
835000ul, // 10
1000000ul, // 11
1500000ul, // 12
2100000ul, // 13
2800000ul, // 14
3600000ul, // 15
4500000ul, // 16
6500000ul, // 17
8000000ul, // 18
10000000ul, // 19
42000000UL // 20
};
if (level < 0 && level >= GUILD_LEVEL_MAX)
return 0;
return CHEONMA_GUILDEXP_LIST[level];
}
static DWORD INTERNATIONAL_GUILDEXP_LIST[GUILD_LEVEL_MAX+1] =
{
0, // 0
6000UL, // 1
18000UL, // 2
36000UL, // 3
64000UL, // 4
94000UL, // 5
130000UL, // 6
172000UL, // 7
220000UL, // 8
274000UL, // 9
334000UL, // 10
400000UL, // 11
600000UL, // 12
840000UL, // 13
1120000UL, // 14
1440000UL, // 15
1800000UL, // 16
2600000UL, // 17
3200000UL, // 18
4000000UL, // 19
16800000UL // 20
0,
6000UL,
18000UL,
36000UL,
64000UL,
94000UL,
130000UL,
172000UL,
220000UL,
274000UL,
334000UL,
400000UL,
600000UL,
840000UL,
1120000UL,
1440000UL,
1800000UL,
2600000UL,
3200000UL,
4000000UL,
16800000UL,
};
if (level < 0 && level >= GUILD_LEVEL_MAX)
// Fix: Correct the condition to ensure 'level' is within valid bounds
if (level < 0 || level > GUILD_LEVEL_MAX)
{
return 0;
return INTERNATIONAL_GUILDEXP_LIST[level];
}
return GUILD_EXP_LIST[level];
}
int LocaleService_GetSkillPower(unsigned level)
int GetSkillPower(unsigned level)
{
static const unsigned SKILL_POWER_NUM = 50;
if (level >= SKILL_POWER_NUM)
{
return 0;
if (LocaleService_IsCHEONMA())
{
static unsigned CHEONMA_SKILL_POWERS[SKILL_POWER_NUM]=
{
0,
5, 7, 9, 11, 13,
15, 17, 19, 20, 22,
24, 26, 28, 30, 32,
34, 36, 38, 40, 50, // master
52, 55, 58, 61, 63,
66, 69, 72, 75, 80, // grand_master
82, 84, 87, 90, 95,
100,110,120,130,150,// perfect_master
150,
};
return CHEONMA_SKILL_POWERS[level];
}
// 0 5 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 50 52 54 56 58 60 63 66 69 72 82 85 88 91 94 98 102 106 110 115 125 125 125 125 125
static unsigned INTERNATIONAL_SKILL_POWERS[SKILL_POWER_NUM]=
static unsigned SKILL_POWERS[SKILL_POWER_NUM] =
{
0,
5, 6, 8, 10, 12,
14, 16, 18, 20, 22,
24, 26, 28, 30, 32,
34, 36, 38, 40, 50, // master
52, 54, 56, 58, 60,
63, 66, 69, 72, 82, // grand_master
85, 88, 91, 94, 98,
102,106,110,115,125,// perfect_master
125,
0,
5, 6, 8, 10, 12,
14, 16, 18, 20, 22,
24, 26, 28, 30, 32,
34, 36, 38, 40, 50,
52, 54, 56, 58, 60,
63, 66, 69, 72, 82,
85, 88, 91, 94, 98,
102, 106, 110, 115, 125,
125,
};
return INTERNATIONAL_SKILL_POWERS[level];
return SKILL_POWERS[level];
}
const char* LocaleService_GetSecurityKey()
const char* GetSecurityKey()
{
return __SECURITY_KEY_STRING__.c_str();
}
// CHEONMA
void LocaleService_SetCHEONMA(bool isEnable)
{
IS_CHEONMA = isEnable;
}
bool LocaleService_IsCHEONMA()
{
return LocaleService_IsYMIR();
}
// END_OF_CHEONMA
#if defined(LOCALE_SERVICE_EUROPE) || defined(LOCALE_SERVICE_BRAZIL) || defined(LOCALE_SERVICE_CANADA) || defined(LOCALE_SERVICE_SINGAPORE) || defined(LOCALE_SERVICE_VIETNAM) || defined(LOCALE_SERVICE_TAIWAN) || defined(LOCALE_SERVICE_NEWCIBN)
#define _LSS_USE_LOCALE_CFG 1
#define _LSS_SERVICE_NAME LSS_EUROPE
#elif defined(LOCALE_SERVICE_ITALY)
#define _LSS_SERVICE_NAME LSS_ITALY
#define _LSS_SERVICE_CODEPAGE CP_LATIN
#define _LSS_SERVICE_LOCALE_NAME "it"
#define _LSS_SERVICE_LOCALE_PATH "locale/it"
#elif defined(LOCALE_SERVICE_ENGLISH)
#define _LSS_SERVICE_NAME LSS_ENGLISH
#define _LSS_SERVICE_CODEPAGE CP_LATIN
#define _LSS_SERVICE_LOCALE_NAME "english"
#define _LSS_SERVICE_LOCALE_PATH "locale/english"
#elif defined(LOCALE_SERVICE_JAPAN)
#define _LSS_SERVICE_NAME LSS_JAPAN
#define _LSS_SERVICE_CODEPAGE CP_JAPANESE
#define _LSS_SERVICE_LOCALE_NAME "japan"
#define _LSS_SERVICE_LOCALE_PATH "locale/japan"
#elif defined(LOCALE_SERVICE_YMIR)
#define _LSS_SERVICE_NAME LSS_YMIR
#define _LSS_SERVICE_CODEPAGE CP_HANGUL
#define _LSS_SERVICE_LOCALE_NAME "ymir"
#define _LSS_SERVICE_LOCALE_PATH "locale/ymir"
#elif defined(LOCALE_SERVICE_HONGKONG)
#define _LSS_SERVICE_NAME LSS_HONGKONG
#define _LSS_SERVICE_CODEPAGE CP_CHINESE_TRAD
#define _LSS_SERVICE_LOCALE_NAME "hongkong"
#define _LSS_SERVICE_LOCALE_PATH "locale/hongkong"
#elif defined(LOCALE_SERVICE_TAIWAN)
#define _LSS_SERVICE_NAME LSS_TAIWAN
#define _LSS_SERVICE_CODEPAGE CP_CHINESE_TRAD
#define _LSS_SERVICE_LOCALE_NAME "taiwan"
#define _LSS_SERVICE_LOCALE_PATH "locale/taiwan"
#elif defined(LOCALE_SERVICE_NEWCIBN)
#define _LSS_SERVICE_NAME LSS_NEWCIBN
#define _LSS_SERVICE_CODEPAGE CP_CHINESE_SIMPLE
#define _LSS_SERVICE_LOCALE_NAME "newcibn"
#define _LSS_SERVICE_LOCALE_PATH "locale/newcibn"
#endif
#if defined(_LSS_USE_LOCALE_CFG)
#if defined(_LSS_SERVICE_NAME)
const char* LocaleService_GetName() { return _LSS_SERVICE_NAME;}
#else
const char* LocaleService_GetName() { return MULTI_LOCALE_SERVICE; }
#endif
unsigned int LocaleService_GetCodePage() { return MULTI_LOCALE_CODE; }
const char* LocaleService_GetLocaleName() { return MULTI_LOCALE_NAME; }
const char* LocaleService_GetLocalePath() { return MULTI_LOCALE_PATH; }
#elif defined(_LSS_SERVICE_NAME)
const char* LocaleService_GetName() { return _LSS_SERVICE_NAME;}
unsigned int LocaleService_GetCodePage() { return _LSS_SERVICE_CODEPAGE; }
const char* LocaleService_GetLocaleName() { return _LSS_SERVICE_LOCALE_NAME; }
const char* LocaleService_GetLocalePath() { return _LSS_SERVICE_LOCALE_PATH; }
#endif
void LocaleService_ForceSetLocale(const char* name, const char* localePath)
{
strcpy(MULTI_LOCALE_NAME, name);
strcpy(MULTI_LOCALE_PATH, localePath);
// 기존 천마 서버로 접속시에는 security key 변경 (WE 버전 클라로 천마서버 접속하기 위함)
if (0 == stricmp(name, "ymir"))
__SECURITY_KEY_STRING__ = "testtesttesttest";
if (0 == stricmp(name, "we_korea"))
__SECURITY_KEY_STRING__ = "1234abcd5678efgh";
}
#if defined(LOCALE_SERVICE_GLOBAL)
struct SLOCALEDATA
{
const char* szServiceName;
const char* szLocaleName;
WORD wCodePage;
const char* szSecurityKey;
} gs_stLocaleData[] = {
{ LSS_YMIR, "ymir", 949, "testtesttesttest" }, // Korea
{ LSS_EUROPE, "en", 1252, "1234abcd5678efgh" }, // GameForge (United Kingdom)
{ LSS_EUROPE, "de", 1252, "1234abcd5678efgh" }, // GameForge (Germany)
{ LSS_EUROPE, "us", 1252, "1234abcd5678efgh" }, // GameForge (USA)
{ LSS_EUROPE, "es", 1252, "1234abcd5678efgh" }, // GameForge (Spain)
{ LSS_EUROPE, "it", 1252, "1234abcd5678efgh" }, // GameForge (Italy)
{ LSS_EUROPE, "fr", 1252, "1234abcd5678efgh" }, // GameForge (France)
{ LSS_EUROPE, "pt", 1252, "1234abcd5678efgh" }, // GameForge (Portugal)
{ LSS_EUROPE, "gr", 1253, "1234abcd5678efgh" }, // GameForge (Greece)
{ LSS_EUROPE, "pl", 1250, "1234abcd5678efgh" }, // GameForge (Poland)
{ LSS_EUROPE, "tr", 1254, "1234abcd5678efgh" }, // GameForge (Turkey)
{ LSS_EUROPE, "dk", 1252, "1234abcd5678efgh" }, // GameForge (Demmark)
{ LSS_EUROPE, "ae", 1256, "1234abcd5678efgh" }, // GameForge (United Arab Emirate)
{ LSS_EUROPE, "mx", 1252, "1234abcd5678efgh" }, // GameForge (Mexico)
{ LSS_EUROPE, "nl", 1252, "1234abcd5678efgh" }, // GameForge (Netherlands)
{ LSS_EUROPE, "cz", 1252, "1234abcd5678efgh" }, // GameForge (Czech Republic)
{ LSS_EUROPE, "ru", 1251, "1234abcd5678efgh" }, // GameForge (Russian Federation)
{ LSS_EUROPE, "hu", 1250, "1234abcd5678efgh" }, // GameForge (Hungary)
{ LSS_EUROPE, "ro", 1250, "1234abcd5678efgh" }, // GameForge (Romania)
{ LSS_EUROPE, "ca", 1252, "testtesttesttest" }, // Z8Games (Canada)
{ LSS_EUROPE, "sg", 1252, "testtesttesttest" }, // TEC (Singapore)
{ LSS_JAPAN, "japan", 932, "testtesttesttest" }, // Japan
{ LSS_EUROPE, "br", 1252, "testtesttesttest" }, // OnGame (Brazil)
{ LSS_HONGKONG, "hongkong", 950, "testtesttesttest" }, // HongKong & Taiwan
{ LSS_NEWCIBN, "newcibn", 936, "testtesttesttest" }, // CIBN (Free world)
{ LSS_ENGLISH, "english", 949, "testtesttesttest" }, // English (Obsoleted)
{ LSS_YMIR, "kr", 949, "testtesttesttest" }, // Korea (Obsoleted)
{ NULL, NULL, 0, "testtesttesttest" }
};
const char* LocaleService_GetName()
{
return MULTI_LOCALE_SERVICE;
}
unsigned int LocaleService_GetCodePage()
{
return MULTI_LOCALE_CODE;
}
const char* LocaleService_GetLocaleName()
const char* GetLocaleName()
{
return MULTI_LOCALE_NAME;
}
const char* LocaleService_GetLocalePath()
const char* GetLocalePath()
{
return MULTI_LOCALE_PATH;
}
static int gs_iLocale = -1;
LRESULT CALLBACK SelectDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
const char* GetLocalePathCommon()
{
switch( uMsg ) {
case WM_INITDIALOG : {
char szLocalePath[256], szDisplayName[256];
for(int i=0; gs_stLocaleData[i].szServiceName; i++ ) {
sprintf(szLocalePath, "locale/%s/item_proto", gs_stLocaleData[i].szLocaleName);
if(CPackManager::Instance().IsExist(szLocalePath)) {
sprintf(szDisplayName, "%s (%s, %d)", gs_stLocaleData[i].szLocaleName, gs_stLocaleData[i].szServiceName, gs_stLocaleData[i].wCodePage);
int iIndex = ListBox_AddString(GetDlgItem(hDlg, IDC_LOCALE_LIST), szDisplayName);
ListBox_SetItemData(GetDlgItem(hDlg, IDC_LOCALE_LIST), iIndex, i);
}
}
return TRUE;
}
case WM_COMMAND :
switch( LOWORD( wParam ) ) {
case IDC_LOCALE_LIST: {
int iSelected = ListBox_GetCurSel(GetDlgItem(hDlg, IDC_LOCALE_LIST));
switch(HIWORD(wParam)) {
case LBN_SELCHANGE :
gs_iLocale = ListBox_GetItemData(GetDlgItem(hDlg, IDC_LOCALE_LIST), iSelected);
break;
case LBN_DBLCLK :
gs_iLocale = ListBox_GetItemData(GetDlgItem(hDlg, IDC_LOCALE_LIST), iSelected);
::EndDialog(hDlg, 0);
break;
}
break;
}
case IDC_START: {
::EndDialog(hDlg, 0);
break;
}
case IDC_EXIT: {
gs_iLocale = -1;
::EndDialog(hDlg, 0);
break;
}
}
return FALSE;
}
return FALSE;
return MULTI_LOCALE_PATH_COMMON;
}
bool LocaleService_LoadGlobal(HINSTANCE hInstance)
bool IsRTL()
{
int nFoundLocales = 0;
char szLocalePath[256];
for(int i=0; gs_stLocaleData[i].szServiceName; i++ ) {
sprintf(szLocalePath, "locale/%s/item_proto", gs_stLocaleData[i].szLocaleName);
if(CPackManager::Instance().IsExist(szLocalePath)) {
nFoundLocales++;
if(gs_iLocale == -1)
gs_iLocale = i;
}
}
if (gs_iLocale < 0)
return false;
if(nFoundLocales > 1)
::DialogBox(hInstance, MAKEINTRESOURCE(IDD_SELECT_LOCALE), NULL, (DLGPROC) SelectDlgProc);
if (gs_iLocale < 0)
return false;
strcpy(MULTI_LOCALE_SERVICE, gs_stLocaleData[gs_iLocale].szServiceName);
strcpy(MULTI_LOCALE_NAME, gs_stLocaleData[gs_iLocale].szLocaleName);
sprintf(MULTI_LOCALE_PATH, "locale/%s", gs_stLocaleData[gs_iLocale].szLocaleName);
MULTI_LOCALE_CODE = gs_stLocaleData[gs_iLocale].wCodePage;
if(gs_stLocaleData[gs_iLocale].szSecurityKey)
__SECURITY_KEY_STRING__ = gs_stLocaleData[gs_iLocale].szSecurityKey;
return true;
}
#else
bool LocaleService_LoadGlobal(HINSTANCE hInstance)
{
return false;
}
#endif
bool LocaleService_IsYMIR() { return (stricmp( LocaleService_GetName(), LSS_YMIR ) == 0) || (stricmp( LocaleService_GetLocaleName(), "ymir" ) == 0); }
bool LocaleService_IsJAPAN() { return (stricmp( LocaleService_GetName(), LSS_JAPAN ) == 0) || (stricmp( LocaleService_GetLocaleName(), "japan" ) == 0); }
bool LocaleService_IsENGLISH() { return (stricmp( LocaleService_GetName(), LSS_ENGLISH ) == 0); }
bool LocaleService_IsEUROPE() { return (stricmp( LocaleService_GetName(), LSS_EUROPE ) == 0); }
bool LocaleService_IsHONGKONG() { return (stricmp( LocaleService_GetName(), LSS_HONGKONG ) == 0); }
bool LocaleService_IsTAIWAN() { return (stricmp( LocaleService_GetName(), LSS_TAIWAN ) == 0); }
bool LocaleService_IsNEWCIBN() { return (stricmp( LocaleService_GetName(), LSS_NEWCIBN ) == 0); }
#if defined(LOCALE_SERVICE_WE_JAPAN)
BOOL LocaleService_IsLeadByte( const char chByte )
{
return ShiftJIS_IsLeadByte( chByte );
return (0 == _stricmp(MULTI_LOCALE_NAME, "ae"));
}
int LocaleService_StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength )
int StringCompareCI(LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength)
{
return ShiftJIS_StringCompareCI( szStringLeft, szStringRight, sizeLength );
return strnicmp (szStringLeft, szStringRight, sizeLength);
}
#else
BOOL LocaleService_IsLeadByte( const char chByte )
{
return (((unsigned char) chByte) & 0x80) != 0;
}
int LocaleService_StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength )
{
return strnicmp( szStringLeft, szStringRight, sizeLength );
}
#endif

View File

@@ -2,30 +2,13 @@
#include "Locale_inc.h"
bool LocaleService_IsYMIR();
bool LocaleService_IsJAPAN();
bool LocaleService_IsENGLISH();
bool LocaleService_IsHONGKONG();
bool LocaleService_IsTAIWAN();
bool LocaleService_IsNEWCIBN();
bool LocaleService_IsEUROPE();
bool LocaleService_IsWorldEdition();
const char* GetLocaleName();
const char* GetLocalePath();
const char* GetLocalePathCommon();
const char* GetSecurityKey();
unsigned LocaleService_GetCodePage();
const char* LocaleService_GetName();
const char* LocaleService_GetLocaleName();
const char* LocaleService_GetLocalePath();
const char* LocaleService_GetSecurityKey();
BOOL LocaleService_IsLeadByte( const char chByte );
int LocaleService_StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength );
void LocaleService_ForceSetLocale(const char* name, const char* localePath);
void LocaleService_LoadConfig(const char* fileName);
bool LocaleService_LoadGlobal(HINSTANCE hInstance);
unsigned LocaleService_GetLastExp(int level);
int LocaleService_GetSkillPower(unsigned level);
// CHEONMA
void LocaleService_SetCHEONMA(bool isEnable);
bool LocaleService_IsCHEONMA();
// END_OF_CHEONMA
bool IsRTL();
int StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength );
void LoadConfig(const char* fileName);
unsigned GetGuildLastExp(int level);
int GetSkillPower(unsigned level);

View File

@@ -1,6 +1,5 @@
#define _IMPROVED_PACKET_ENCRYPTION_
#define LOCALE_SERVICE_GLOBAL
#define ENABLE_COSTUME_SYSTEM
#define ENABLE_ENERGY_SYSTEM
#define ENABLE_DRAGON_SOUL_SYSTEM

View File

@@ -372,15 +372,19 @@ HRESULT CMovieMan::RenderFileToMMStream(const char *cpFilename, IMultiMediaStrea
}
WCHAR wPath[MAX_PATH + 1];
MultiByteToWideChar(CP_ACP, 0, cpFilename, -1, wPath, MAX_PATH + 1);
int ok = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, cpFilename, -1, wPath, MAX_PATH + 1);
if (ok <= 0)
return E_FAIL;
//
WCHAR wsDir[MAX_PATH + 1];
::memset(wsDir, 0, sizeof(wsDir));
::GetCurrentDirectoryW( MAX_PATH, wsDir );
::wcsncat( wsDir, L"\\", sizeof(WCHAR)*1 );
::wcsncat( wsDir, wPath, sizeof(WCHAR)*::wcsnlen(wPath, MAX_PATH) );
wcscat_s(wsDir, MAX_PATH + 1, L"\\");
wcscat_s(wsDir, MAX_PATH + 1, wPath);
::memset(wPath, 0, sizeof(wPath));
::wcsncpy( wPath, wsDir, sizeof(WCHAR)*::wcsnlen(wsDir, MAX_PATH) );
wcsncpy_s(wPath, MAX_PATH + 1, wsDir, _TRUNCATE);
//
pAMStream->Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, NULL);

View File

@@ -1,57 +1,60 @@
#include "StdAfx.h"
#include <tlhelp32.h>
#include <utf8.h>
static BYTE abCRCMagicCube[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
static BYTE abCRCXorTable[8] = { 102, 30, 188, 44, 39, 201, 43, 5 };
static BYTE bMagicCubeIdx = 0;
const char * stristr(const char * big, const char * little)
const wchar_t* wcsistr(const wchar_t* haystack, const wchar_t* needle)
{
const char * t = big;
size_t len = strlen(little) - 1;
if (!haystack || !needle || !*needle)
return haystack;
for (t = big; *t; ++t)
if (!_strnicmp(t, little, len))
return t;
size_t needleLen = wcslen(needle);
return NULL;
for (const wchar_t* p = haystack; *p; ++p)
{
if (_wcsnicmp(p, needle, needleLen) == 0)
return p;
}
return nullptr;
}
bool GetProcessInformation(std::string & exeFileName, LPCVOID * ppvAddress)
bool GetProcessInformation(std::string& exeFileName, LPCVOID* ppvAddress)
{
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if (hModuleSnap != INVALID_HANDLE_VALUE)
{
std::string filename;
HANDLE hModuleSnap = CreateToolhelp32Snapshot(
TH32CS_SNAPMODULE,
GetCurrentProcessId());
GetExcutedFileName(filename);
if (hModuleSnap == INVALID_HANDLE_VALUE)
return false;
MODULEENTRY32 me32;
memset(&me32, 0, sizeof(me32));
me32.dwSize = sizeof(MODULEENTRY32);
std::string exeUtf8;
GetExcutedFileName(exeUtf8);
BOOL bRet = Module32First(hModuleSnap, &me32);
std::wstring exeWide = Utf8ToWide(exeUtf8);
while (bRet)
MODULEENTRY32W me32{};
me32.dwSize = sizeof(me32);
BOOL bRet = Module32FirstW(hModuleSnap, &me32);
while (bRet)
{
if (wcsistr(me32.szExePath, exeWide.c_str()))
{
if (stristr(me32.szExePath, filename.c_str()))
{
exeFileName = me32.szExePath;
*ppvAddress = me32.modBaseAddr;
CloseHandle(hModuleSnap);
return true;
}
ZeroMemory(&me32, sizeof(MODULEENTRY32));
me32.dwSize = sizeof(MODULEENTRY32);
bRet = Module32Next(hModuleSnap, &me32);
exeFileName = WideToUtf8(me32.szExePath);
*ppvAddress = me32.modBaseAddr;
CloseHandle(hModuleSnap);
return true;
}
CloseHandle(hModuleSnap);
me32.dwSize = sizeof(me32);
bRet = Module32NextW(hModuleSnap, &me32);
}
CloseHandle(hModuleSnap);
return false;
}
@@ -95,13 +98,6 @@ bool __GetExeCRC(DWORD & r_dwProcCRC, DWORD & r_dwFileCRC)
void BuildProcessCRC()
{
if (LocaleService_IsHONGKONG() || LocaleService_IsTAIWAN())
{
memset(abCRCMagicCube, 0, sizeof(abCRCMagicCube));
bMagicCubeIdx = 0;
return;
}
DWORD dwProcCRC, dwFileCRC;
if (__GetExeCRC(dwProcCRC, dwFileCRC))

View File

@@ -2,6 +2,7 @@
#include "ProcessScanner.h"
#include <tlhelp32.h>
#include <utf8.h>
static std::vector<CRCPair> gs_kVct_crcPair;
static CRITICAL_SECTION gs_csData;
@@ -11,61 +12,64 @@ static HANDLE gs_hThread=NULL;
void ScanProcessList(std::map<DWORD, DWORD>& rkMap_crcProc, std::vector<CRCPair>* pkVct_crcPair)
{
SYSTEM_INFO si;
memset(&si, 0, sizeof(si));
GetSystemInfo(&si);
SYSTEM_INFO si{};
GetSystemInfo(&si);
PROCESSENTRY32 pro;
pro.dwSize = sizeof(PROCESSENTRY32);
PROCESSENTRY32W pro{};
pro.dwSize = sizeof(PROCESSENTRY32W);
LPPROCESSENTRY32 Entry;
Entry = &pro;
HANDLE processSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (processSnap == INVALID_HANDLE_VALUE)
return;
HANDLE process = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
BOOL bOK = Process32FirstW(processSnap, &pro);
BOOL bOK = Process32First(process, Entry);
while(bOK)
while (bOK)
{
HANDLE hProc = OpenProcess(PROCESS_VM_READ, FALSE, Entry->th32ProcessID);
if (hProc)
{
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Entry->th32ProcessID);
if (hModuleSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 me32;
memset(&me32, 0, sizeof(me32));
me32.dwSize = sizeof(MODULEENTRY32);
HANDLE hProc = OpenProcess(PROCESS_VM_READ, FALSE, pro.th32ProcessID);
if (hProc)
{
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pro.th32ProcessID);
if (hModuleSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32W me32{};
me32.dwSize = sizeof(MODULEENTRY32W);
BOOL bRet = Module32First(hModuleSnap, &me32);
while (bRet)
{
DWORD crcExtPath=GetCRC32((const char*)me32.szExePath, strlen(me32.szExePath));
BOOL bRet = Module32FirstW(hModuleSnap, &me32);
while (bRet)
{
// Wide exe path -> UTF-8 bytes (for CRC / engine use)
std::string exePathUtf8 = WideToUtf8(me32.szExePath);
std::map<DWORD, DWORD>::iterator f=rkMap_crcProc.find(crcExtPath);
if (rkMap_crcProc.end()==f)
{
DWORD crcProc=GetFileCRC32(me32.szExePath);
rkMap_crcProc.insert(std::make_pair(crcExtPath, crcProc));
pkVct_crcPair->push_back(std::make_pair(crcProc, (const char*)me32.szExePath));
}
Sleep(1);
ZeroMemory(&me32, sizeof(MODULEENTRY32));
me32.dwSize = sizeof(MODULEENTRY32);
bRet = Module32Next(hModuleSnap, &me32);
}
DWORD crcExtPath = GetCRC32(exePathUtf8.c_str(), (int)exePathUtf8.size());
CloseHandle(hModuleSnap);
}
auto f = rkMap_crcProc.find(crcExtPath);
if (f == rkMap_crcProc.end())
{
// Make sure GetFileCRC32 is Unicode-safe:
DWORD crcProc = GetFileCRC32(me32.szExePath); // best
rkMap_crcProc.insert(std::make_pair(crcExtPath, crcProc));
CloseHandle(hProc);
}
pkVct_crcPair->push_back(std::make_pair(crcProc, exePathUtf8));
}
bOK = Process32Next(process, Entry);
Sleep(1);
me32.dwSize = sizeof(MODULEENTRY32W);
bRet = Module32NextW(hModuleSnap, &me32);
}
CloseHandle(hModuleSnap);
}
CloseHandle(hProc);
}
bOK = Process32NextW(processSnap, &pro);
pro.dwSize = sizeof(PROCESSENTRY32W);
}
CloseHandle(process);
CloseHandle(processSnap);
}
void ProcessScanner_ReleaseQuitEvent()
@@ -122,8 +126,8 @@ void ProcessScanner_Thread(void* pv)
bool ProcessScanner_Create()
{
InitializeCriticalSection(&gs_csData);
gs_evReqExit=CreateEvent(NULL, FALSE, FALSE, "ProcessScanner_ReqExit");
gs_evResExit=CreateEvent(NULL, FALSE, FALSE, "ProcessScanner_ResExit");
gs_evReqExit=CreateEvent(NULL, FALSE, FALSE, L"ProcessScanner_ReqExit");
gs_evResExit=CreateEvent(NULL, FALSE, FALSE, L"ProcessScanner_ResExit");
gs_hThread=(HANDLE)_beginthread(ProcessScanner_Thread, 64*1024, NULL);
if (INVALID_HANDLE_VALUE==gs_hThread)

View File

@@ -11,6 +11,8 @@
#include "ProcessScanner.h"
#include <utf8.h>
extern void GrannyCreateSharedDeformBuffer();
extern void GrannyDestroySharedDeformBuffer();
@@ -742,82 +744,65 @@ int CPythonApplication::CheckDeviceState()
return DEVICE_STATE_OK;
}
bool CPythonApplication::CreateDevice(int width, int height, int Windowed, int bit /* = 32*/, int frequency /* = 0*/)
bool CPythonApplication::CreateDevice(int width, int height, int Windowed, int bit, int frequency)
{
int iRet;
m_grpDevice.InitBackBufferCount(2);
m_grpDevice.RegisterWarningString(CGraphicDevice::CREATE_BAD_DRIVER, ApplicationStringTable_GetStringz(IDS_WARN_BAD_DRIVER, "WARN_BAD_DRIVER"));
m_grpDevice.RegisterWarningString(CGraphicDevice::CREATE_NO_TNL, ApplicationStringTable_GetStringz(IDS_WARN_NO_TNL, "WARN_NO_TNL"));
iRet = m_grpDevice.Create(GetWindowHandle(), width, height, Windowed ? true : false, bit,frequency);
iRet = m_grpDevice.Create(GetWindowHandle(), width, height, Windowed ? true : false, bit, frequency);
switch (iRet)
{
case CGraphicDevice::CREATE_OK:
return true;
case CGraphicDevice::CREATE_REFRESHRATE:
return true;
case CGraphicDevice::CREATE_ENUM:
case CGraphicDevice::CREATE_DETECT:
SET_EXCEPTION(CREATE_NO_APPROPRIATE_DEVICE);
TraceError("CreateDevice: Enum & Detect failed");
return false;
case CGraphicDevice::CREATE_NO_DIRECTX:
//PyErr_SetString(PyExc_RuntimeError, "DirectX 8.1 or greater required to run game");
SET_EXCEPTION(CREATE_NO_DIRECTX);
TraceError("CreateDevice: DirectX 8.1 or greater required to run game");
return false;
case CGraphicDevice::CREATE_DEVICE:
//PyErr_SetString(PyExc_RuntimeError, "GraphicDevice create failed");
SET_EXCEPTION(CREATE_DEVICE);
TraceError("CreateDevice: GraphicDevice create failed");
return false;
case CGraphicDevice::CREATE_FORMAT:
SET_EXCEPTION(CREATE_FORMAT);
TraceError("CreateDevice: Change the screen format");
return false;
/*case CGraphicDevice::CREATE_GET_ADAPTER_DISPLAY_MODE:
//PyErr_SetString(PyExc_RuntimeError, "GetAdapterDisplayMode failed");
SET_EXCEPTION(CREATE_GET_ADAPTER_DISPLAY_MODE);
TraceError("CreateDevice: GetAdapterDisplayMode failed");
return false;*/
case CGraphicDevice::CREATE_GET_DEVICE_CAPS:
PyErr_SetString(PyExc_RuntimeError, "GetDevCaps failed");
TraceError("CreateDevice: GetDevCaps failed");
return false;
case CGraphicDevice::CREATE_GET_DEVICE_CAPS2:
PyErr_SetString(PyExc_RuntimeError, "GetDevCaps2 failed");
TraceError("CreateDevice: GetDevCaps2 failed");
return false;
default:
if (iRet & CGraphicDevice::CREATE_OK)
{
//if (iRet & CGraphicDevice::CREATE_BAD_DRIVER)
//{
// LogBox(ApplicationStringTable_GetStringz(IDS_WARN_BAD_DRIVER), NULL, GetWindowHandle());
//}
if (iRet & CGraphicDevice::CREATE_NO_TNL)
{
CGrannyLODController::SetMinLODMode(true);
//LogBox(ApplicationStringTable_GetStringz(IDS_WARN_NO_TNL), NULL, GetWindowHandle());
}
case CGraphicDevice::CREATE_OK:
return true;
}
//PyErr_SetString(PyExc_RuntimeError, "Unknown Error!");
SET_EXCEPTION(UNKNOWN_ERROR);
TraceError("CreateDevice: Unknown Error!");
return false;
case CGraphicDevice::CREATE_REFRESHRATE:
return true;
case CGraphicDevice::CREATE_ENUM:
case CGraphicDevice::CREATE_DETECT:
SET_EXCEPTION(CREATE_NO_APPROPRIATE_DEVICE);
TraceError("CreateDevice: Enum & Detect failed");
return false;
case CGraphicDevice::CREATE_NO_DIRECTX:
SET_EXCEPTION(CREATE_NO_DIRECTX);
TraceError("CreateDevice: DirectX 8.1 or greater required to run game");
return false;
case CGraphicDevice::CREATE_DEVICE:
SET_EXCEPTION(CREATE_DEVICE);
TraceError("CreateDevice: GraphicDevice create failed");
return false;
case CGraphicDevice::CREATE_FORMAT:
SET_EXCEPTION(CREATE_FORMAT);
TraceError("CreateDevice: Change the screen format");
return false;
case CGraphicDevice::CREATE_GET_DEVICE_CAPS:
PyErr_SetString(PyExc_RuntimeError, "GetDevCaps failed");
TraceError("CreateDevice: GetDevCaps failed");
return false;
case CGraphicDevice::CREATE_GET_DEVICE_CAPS2:
PyErr_SetString(PyExc_RuntimeError, "GetDevCaps2 failed");
TraceError("CreateDevice: GetDevCaps2 failed");
return false;
default:
if (iRet & CGraphicDevice::CREATE_OK)
{
if (iRet & CGraphicDevice::CREATE_NO_TNL)
{
CGrannyLODController::SetMinLODMode(true);
}
return true;
}
SET_EXCEPTION(UNKNOWN_ERROR);
TraceError("CreateDevice: Unknown Error!");
return false;
}
}
@@ -840,38 +825,37 @@ void CPythonApplication::Loop()
}
}
// SUPPORT_NEW_KOREA_SERVER
bool LoadLocaleData(const char* localePath)
{
NANOBEGIN
CPythonNonPlayer& rkNPCMgr = CPythonNonPlayer::Instance();
CPythonNonPlayer& rkNPCMgr = CPythonNonPlayer::Instance();
CItemManager& rkItemMgr = CItemManager::Instance();
CPythonSkill& rkSkillMgr = CPythonSkill::Instance();
CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance();
char szItemList[256];
char szItemProto[256];
char szItemDesc[256];
char szItemDesc[256];
char szMobProto[256];
char szSkillDescFileName[256];
char szSkillTableFileName[256];
char szInsultList[256];
snprintf(szItemList, sizeof(szItemList) , "%s/item_list.txt", localePath);
snprintf(szItemProto, sizeof(szItemProto), "%s/item_proto", localePath);
snprintf(szItemDesc, sizeof(szItemDesc), "%s/itemdesc.txt", localePath);
snprintf(szMobProto, sizeof(szMobProto), "%s/mob_proto", localePath);
snprintf(szSkillDescFileName, sizeof(szSkillDescFileName), "%s/SkillDesc.txt", localePath);
snprintf(szSkillTableFileName, sizeof(szSkillTableFileName), "%s/SkillTable.txt", localePath);
snprintf(szInsultList, sizeof(szInsultList), "%s/insult.txt", localePath);
snprintf (szItemList, sizeof (szItemList), "%s/item_list.txt", GetLocalePathCommon());
snprintf (szItemProto, sizeof (szItemProto), "%s/item_proto", localePath);
snprintf (szItemDesc, sizeof (szItemDesc), "%s/itemdesc.txt", localePath);
snprintf (szMobProto, sizeof (szMobProto), "%s/mob_proto", localePath);
snprintf (szSkillDescFileName, sizeof (szSkillDescFileName), "%s/SkillDesc.txt", localePath);
snprintf (szSkillTableFileName, sizeof (szSkillTableFileName), "%s/SkillTable.txt", GetLocalePathCommon());
snprintf (szInsultList, sizeof (szInsultList), "%s/insult.txt", localePath);
rkNPCMgr.Destroy();
rkItemMgr.Destroy();
rkItemMgr.Destroy();
rkSkillMgr.Destroy();
if (!rkItemMgr.LoadItemList(szItemList))
{
TraceError("LoadLocaleData - LoadItemList(%s) Error", szItemList);
}
}
if (!rkItemMgr.LoadItemTable(szItemProto))
{
@@ -881,7 +865,7 @@ bool LoadLocaleData(const char* localePath)
if (!rkItemMgr.LoadItemDesc(szItemDesc))
{
Tracenf("LoadLocaleData - LoadItemDesc(%s) Error", szItemDesc);
Tracenf("LoadLocaleData - LoadItemDesc(%s) Error", szItemDesc);
}
if (!rkNPCMgr.LoadNonPlayerData(szMobProto))
@@ -904,26 +888,11 @@ bool LoadLocaleData(const char* localePath)
if (!rkNetStream.LoadInsultList(szInsultList))
{
Tracenf("CPythonApplication - CPythonNetworkStream::LoadInsultList(%s)", szInsultList);
Tracenf("CPythonApplication - CPythonNetworkStream::LoadInsultList(%s)", szInsultList);
}
if (LocaleService_IsYMIR())
{
char szEmpireTextConvFile[256];
for (DWORD dwEmpireID=1; dwEmpireID<=3; ++dwEmpireID)
{
sprintf(szEmpireTextConvFile, "%s/lang%d.cvt", localePath, dwEmpireID);
if (!rkNetStream.LoadConvertTable(dwEmpireID, szEmpireTextConvFile))
{
TraceError("LoadLocaleData - CPythonNetworkStream::LoadConvertTable(%d, %s) FAILURE", dwEmpireID, szEmpireTextConvFile);
}
}
}
NANOEND
return true;
return true;
}
// END_OF_SUPPORT_NEW_KOREA_SERVER
unsigned __GetWindowMode(bool windowed)
{
@@ -940,7 +909,9 @@ bool CPythonApplication::Create(PyObject * poSelf, const char * c_szName, int wi
bool bAnotherWindow = false;
if (FindWindow(NULL, c_szName))
std::wstring wWindowName = Utf8ToWide(c_szName ? c_szName : "");
if (FindWindowW(nullptr, wWindowName.c_str()))
bAnotherWindow = true;
m_dwWidth = width;
@@ -951,7 +922,6 @@ bool CPythonApplication::Create(PyObject * poSelf, const char * c_szName, int wi
if (!CMSWindow::Create(c_szName, 4, 0, WindowMode, ::LoadIcon( GetInstance(), MAKEINTRESOURCE( IDI_METIN2 ) ), IDC_CURSOR_NORMAL))
{
//PyErr_SetString(PyExc_RuntimeError, "CMSWindow::Create failed");
TraceError("CMSWindow::Create failed");
SET_EXCEPTION(CREATE_WINDOW);
return false;
@@ -966,10 +936,7 @@ bool CPythonApplication::Create(PyObject * poSelf, const char * c_szName, int wi
m_pyNetworkStream.Discord_Start();
#endif
// Ç®½ºÅ©¸° ¸ðµåÀ̰í
// µðÆúÆ® IME ¸¦ »ç¿ëÇϰųª À¯·´ ¹öÀüÀ̸é
// À©µµ¿ì Ç®½ºÅ©¸° ¸ðµå¸¦ »ç¿ëÇÑ´Ù
if (!m_pySystem.IsWindowed() && (m_pySystem.IsUseDefaultIME() || LocaleService_IsEUROPE()))
if (!m_pySystem.IsWindowed())
{
m_isWindowed = false;
m_isWindowFullScreenEnable = TRUE;
@@ -1012,7 +979,6 @@ bool CPythonApplication::Create(PyObject * poSelf, const char * c_szName, int wi
// Cursor
if (!CreateCursors())
{
//PyErr_SetString(PyExc_RuntimeError, "CMSWindow::Cursors Create Error");
TraceError("CMSWindow::Cursors Create Error");
SET_EXCEPTION("CREATE_CURSOR");
return false;
@@ -1057,7 +1023,7 @@ bool CPythonApplication::Create(PyObject * poSelf, const char * c_szName, int wi
SetVisibleMode(true);
if (m_isWindowFullScreenEnable) //m_pySystem.IsUseDefaultIME() && !m_pySystem.IsWindowed())
if (m_isWindowFullScreenEnable)
{
SetWindowPos(GetWindowHandle(), HWND_TOP, 0, 0, width, height, SWP_SHOWWINDOW);
}
@@ -1076,7 +1042,6 @@ bool CPythonApplication::Create(PyObject * poSelf, const char * c_szName, int wi
// Network
if (!m_netDevice.Create())
{
//PyErr_SetString(PyExc_RuntimeError, "NetDevice::Create failed");
TraceError("NetDevice::Create failed");
SET_EXCEPTION("CREATE_NETWORK");
return false;

View File

@@ -226,7 +226,6 @@ class CPythonApplication : public CMSApplication, public CInputKeyboard, public
void RunIMEReturnEvent();
void RunPressExitKey();
void RunIMEChangeCodePage();
void RunIMEOpenCandidateListEvent();
void RunIMECloseCandidateListEvent();
void RunIMEOpenReadingWndEvent();

View File

@@ -4,6 +4,8 @@
#include "EterBase/timer.h"
#include "EterLib/Camera.h"
#include <utf8.h>
float BlendValueByLinear(float fElapsedTime, float fDuration, float fBeginValue, float fEndValue)
{
if (fElapsedTime >= fDuration)
@@ -359,8 +361,14 @@ void CPythonApplication::SaveCameraSetting(const char * c_szFileName)
SCameraSetting CameraSetting;
GetCameraSetting(&CameraSetting);
FILE * File = fopen(c_szFileName, "w");
SetFileAttributes(c_szFileName, FILE_ATTRIBUTE_NORMAL);
// UTF-8 → UTF-16
std::wstring wFileName = Utf8ToWide(c_szFileName);
FILE* File = _wfopen(wFileName.c_str(), L"w");
if (!File)
return;
SetFileAttributesW(wFileName.c_str(), FILE_ATTRIBUTE_NORMAL);
PrintfTabs(File, 0, "CenterPos %f %f %f\n", CameraSetting.v3CenterPosition.x, CameraSetting.v3CenterPosition.y, CameraSetting.v3CenterPosition.z);
PrintfTabs(File, 0, "CameraSetting %f %f %f\n", CameraSetting.fZoom, CameraSetting.fPitch, CameraSetting.fRotation);

View File

@@ -166,11 +166,6 @@ void CPythonApplication::OnIMEKeyDown(int iIndex)
}
/////////////////////////////
void CPythonApplication::RunIMEChangeCodePage()
{
UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance();
rkWndMgr.RunChangeCodePage();
}
void CPythonApplication::RunIMEOpenCandidateListEvent()
{
UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance();

View File

@@ -41,7 +41,11 @@ int CPythonApplication::OnLogoOpen(char* szName)
// Render File
WCHAR wFileName[ MAX_PATH ];
MultiByteToWideChar(CP_ACP, 0, szName, -1, wFileName, MAX_PATH);
int ok = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, szName, -1, wFileName, MAX_PATH);
if (ok <= 0)
return 0;
if(FAILED(m_pGraphBuilder->RenderFile(wFileName, NULL))) { return 0; }
IBaseFilter* pSrc;

View File

@@ -3,8 +3,10 @@
#include "PythonApplication.h"
#include "EterLib/Camera.h"
#include "PackLib/PackManager.h"
#include "EterBase/tea.h"
#include <stb_image.h>
#include <utf8.h>
extern D3DXCOLOR g_fSpecularColor;
extern BOOL bVisibleNotice = true;
@@ -29,7 +31,7 @@ PyObject* appShowWebPage(PyObject* poSelf, PyObject* poArgs)
CPythonApplication::Instance().ShowWebPage(
szWebPage,
rcWebPage
rcWebPage
);
return Py_BuildNone();
}
@@ -215,80 +217,8 @@ PyObject* appSetFrameSkip(PyObject* poSelf, PyObject* poArgs)
}
// LOCALE
PyObject* appForceSetLocale(PyObject* poSelf, PyObject* poArgs)
{
char* szName;
if (!PyTuple_GetString(poArgs, 0, &szName))
return Py_BuildException();
char* szLocalePath;
if (!PyTuple_GetString(poArgs, 1, &szLocalePath))
return Py_BuildException();
LocaleService_ForceSetLocale(szName, szLocalePath);
return Py_BuildNone();
}
PyObject* appGetLocaleServiceName(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("s", LocaleService_GetName());
}
//
bool LoadLocaleData(const char* localePath);
PyObject* appSetCHEONMA(PyObject* poSelf, PyObject* poArgs)
{
int enable;
if (!PyTuple_GetInteger(poArgs, 0, &enable))
return Py_BuildException();
LocaleService_SetCHEONMA(enable ? true : false);
return Py_BuildNone();
}
PyObject* appIsCHEONMA(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("i", LocaleService_IsCHEONMA());
}
#include "EterBase/tea.h"
PyObject* appLoadLocaleAddr(PyObject* poSelf, PyObject* poArgs)
{
char* addrPath;
if (!PyTuple_GetString(poArgs, 0, &addrPath))
return Py_BuildException();
FILE* fp = fopen(addrPath, "rb");
if (!fp)
return Py_BuildException();
fseek(fp, 0, SEEK_END);
int size = ftell(fp);
char* enc = (char*)_alloca(size);
fseek(fp, 0, SEEK_SET);
fread(enc, size, 1, fp);
fclose(fp);
static const unsigned char key[16] = {
0x82, 0x1b, 0x34, 0xae,
0x12, 0x3b, 0xfb, 0x17,
0xd7, 0x2c, 0x39, 0xae,
0x41, 0x98, 0xf1, 0x63
};
char* buf = (char*)_alloca(size);
//int decSize =
tea_decrypt((unsigned long*)buf, (const unsigned long*)enc, (const unsigned long*)key, size);
unsigned int retSize = *(unsigned int*)buf;
char* ret = buf + sizeof(unsigned int);
return Py_BuildValue("s#", ret, retSize);
}
PyObject* appLoadLocaleData(PyObject* poSelf, PyObject* poArgs)
{
char* localePath;
@@ -300,20 +230,20 @@ PyObject* appLoadLocaleData(PyObject* poSelf, PyObject* poArgs)
PyObject* appGetLocaleName(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("s", LocaleService_GetLocaleName());
return Py_BuildValue("s", GetLocaleName());
}
PyObject* appGetLocalePath(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("s", LocaleService_GetLocalePath());
return Py_BuildValue("s", GetLocalePath());
}
PyObject* appGetLocalePathCommon(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("s", GetLocalePathCommon());
}
// END_OF_LOCALE
PyObject* appGetDefaultCodePage(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("i", LocaleService_GetCodePage());
}
#ifdef __VTUNE__
PyObject* appGetImageInfo(PyObject* poSelf, PyObject* poArgs)
@@ -353,25 +283,25 @@ PyObject* appIsExistFile(PyObject* poSelf, PyObject* poArgs)
PyObject* appGetFileList(PyObject* poSelf, PyObject* poArgs)
{
char* szFilter;
char* szFilter = nullptr;
if (!PyTuple_GetString(poArgs, 0, &szFilter))
return Py_BuildException();
PyObject* poList=PyList_New(0);
std::wstring wFilter = Utf8ToWide(szFilter ? szFilter : "");
WIN32_FIND_DATA wfd;
memset(&wfd, 0, sizeof(wfd));
PyObject* poList = PyList_New(0);
HANDLE hFind = FindFirstFile(szFilter, &wfd);
WIN32_FIND_DATAW wfd{};
HANDLE hFind = FindFirstFileW(wFilter.c_str(), &wfd);
if (hFind != INVALID_HANDLE_VALUE)
{
{
do
{
PyObject* poFileName=PyString_FromString(wfd.cFileName) ;
std::string filenameUtf8 = WideToUtf8(wfd.cFileName);
PyObject* poFileName = PyString_FromString(filenameUtf8.c_str());
PyList_Append(poList, poFileName);
}
while (FindNextFile(hFind, &wfd));
Py_DECREF(poFileName);
} while (FindNextFileW(hFind, &wfd));
FindClose(hFind);
}
@@ -379,7 +309,6 @@ PyObject* appGetFileList(PyObject* poSelf, PyObject* poArgs)
return poList;
}
PyObject* appUpdateGame(PyObject* poSelf, PyObject* poArgs)
{
CPythonApplication::Instance().UpdateGame();
@@ -1093,56 +1022,29 @@ PyObject * appSetGuildMarkPath(PyObject * poSelf, PyObject * poArgs)
if (!PyTuple_GetString(poArgs, 0, &path))
return Py_BuildException();
char newPath[256];
char * ext = strstr(path, ".tga");
char newPath[256];
char * ext = strstr(path, ".tga");
if (ext)
{
if (ext)
{
int extPos = ext - path;
strncpy(newPath, path, extPos);
newPath[extPos] = '\0';
}
else
strncpy(newPath, path, sizeof(newPath)-1);
strncpy(newPath, path, extPos);
newPath[extPos] = '\0';
}
else
strncpy(newPath, path, sizeof(newPath)-1);
CGuildMarkManager::Instance().SetMarkPathPrefix(newPath);
return Py_BuildNone();
}
PyObject* appIsDevStage(PyObject* poSelf, PyObject* poArgs)
{
int nIsDevelopmentStage = 0;
#if defined(LOCALE_SERVICE_STAGE_DEVELOPMENT)
nIsDevelopmentStage = 1;
#endif
return Py_BuildValue("i", nIsDevelopmentStage);
}
PyObject* appIsTestStage(PyObject* poSelf, PyObject* poArgs)
{
int nIsTestStage = 0;
#if defined(LOCALE_SERVICE_STAGE_TEST)
nIsTestStage = 1;
#endif
return Py_BuildValue("i", nIsTestStage);
}
PyObject* appIsLiveStage(PyObject* poSelf, PyObject* poArgs)
{
int nIsLiveStage = 0;
#if !defined(LOCALE_SERVICE_STAGE_TEST) && !defined(LOCALE_SERVICE_STAGE_DEVELOPMENT)
nIsLiveStage = 1;
#endif
return Py_BuildValue("i", nIsLiveStage);
}
PyObject* appLogoOpen(PyObject* poSelf, PyObject* poArgs)
{
char* szName;
if (!PyTuple_GetString(poArgs, 0, &szName))
return Py_BuildException();
int nIsSuccess = 1; //CPythonApplication::Instance().OnLogoOpen(szName);
int nIsSuccess = 1;
CMovieMan::Instance().PlayLogo(szName);
return Py_BuildValue("i", nIsSuccess);
@@ -1150,7 +1052,7 @@ PyObject* appLogoOpen(PyObject* poSelf, PyObject* poArgs)
PyObject* appLogoUpdate(PyObject* poSelf, PyObject* poArgs)
{
int nIsRun = 0; //CPythonApplication::Instance().OnLogoUpdate();
int nIsRun = 0;
return Py_BuildValue("i", nIsRun);
}
@@ -1166,21 +1068,22 @@ PyObject* appLogoClose(PyObject* poSelf, PyObject* poArgs)
return Py_BuildNone();
}
PyObject* appIsRTL(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("i", IsRTL() ? 1 : 0);
}
void initapp()
{
static PyMethodDef s_methods[] =
{
{ "IsDevStage", appIsDevStage, METH_VARARGS },
{ "IsTestStage", appIsTestStage, METH_VARARGS },
{ "IsLiveStage", appIsLiveStage, METH_VARARGS },
{
// TEXTTAIL_LIVINGTIME_CONTROL
{ "SetTextTailLivingTime", appSetTextTailLivingTime, METH_VARARGS },
// END_OF_TEXTTAIL_LIVINGTIME_CONTROL
{ "EnablePerformanceTime", appEnablePerformanceTime, METH_VARARGS },
{ "SetHairColorEnable", appSetHairColorEnable, METH_VARARGS },
{ "SetArmorSpecularEnable", appSetArmorSpecularEnable, METH_VARARGS },
{ "SetWeaponSpecularEnable", appSetWeaponSpecularEnable, METH_VARARGS },
{ "SetSkillEffectUpgradeEnable",appSetSkillEffectUpgradeEnable, METH_VARARGS },
@@ -1273,20 +1176,13 @@ void initapp()
{ "GetTextFileLine", appGetTextFileLine, METH_VARARGS },
// LOCALE
{ "GetLocaleServiceName", appGetLocaleServiceName, METH_VARARGS },
{ "GetLocaleName", appGetLocaleName, METH_VARARGS },
{ "GetLocalePath", appGetLocalePath, METH_VARARGS },
{ "ForceSetLocale", appForceSetLocale, METH_VARARGS },
{ "GetLocalePathCommon", appGetLocalePathCommon, METH_VARARGS },
{ "LoadLocaleData", appLoadLocaleData, METH_VARARGS },
{ "IsRTL", appIsRTL, METH_VARARGS },
// END_OF_LOCALE
// CHEONMA
{ "LoadLocaleAddr", appLoadLocaleAddr, METH_VARARGS },
{ "LoadLocaleData", appLoadLocaleData, METH_VARARGS },
{ "SetCHEONMA", appSetCHEONMA, METH_VARARGS },
{ "IsCHEONMA", appIsCHEONMA, METH_VARARGS },
// END_OF_CHEONMA
{ "GetDefaultCodePage", appGetDefaultCodePage, METH_VARARGS },
{ "SetControlFP", appSetControlFP, METH_VARARGS },
{ "SetSpecularSpeed", appSetSpecularSpeed, METH_VARARGS },
@@ -1305,6 +1201,7 @@ void initapp()
{ "OnLogoRender", appLogoRender, METH_VARARGS },
{ "OnLogoOpen", appLogoOpen, METH_VARARGS },
{ "OnLogoClose", appLogoClose, METH_VARARGS },
{ NULL, NULL },
};

View File

@@ -233,7 +233,7 @@ CPythonBackground::~CPythonBackground()
void CPythonBackground::Initialize()
{
std::string stAtlasInfoFileName (LocaleService_GetLocalePath());
std::string stAtlasInfoFileName(GetLocalePath());
stAtlasInfoFileName += "/AtlasInfo.txt";
SetAtlasInfoFileName(stAtlasInfoFileName.c_str());
CMapManager::Initialize();

View File

@@ -5,6 +5,8 @@
#include "PythonCharacterManager.h"
#include "EterBase/Timer.h"
#include <utf8.h>
int CPythonChat::TChatSet::ms_iChatModeSize = CHAT_TYPE_MAX_NUM;
const float c_fStartDisappearingTime = 5.0f;
@@ -135,7 +137,13 @@ void CPythonChat::UpdateViewMode(DWORD dwID)
--iLineIndex;
pChatLine->Instance.SetPosition(pChatSet->m_ix, pChatSet->m_iy + iHeight);
pChatLine->Instance.SetColor(rColor);
pChatLine->Instance.SetColor(pChatLine->GetColorRef(dwID));
if (pChatSet->m_iAlign == 1)
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::RTL);
else
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::LTR);
pChatLine->Instance.Update();
}
}
@@ -146,7 +154,7 @@ void CPythonChat::UpdateEditMode(DWORD dwID)
if (!pChatSet)
return;
const int c_iAlphaLine = std::max(0, GetVisibleLineCount(dwID) - GetEditableLineCount(dwID) + 2);
const int c_iAlphaLine = (std::max)(0, GetVisibleLineCount(dwID) - GetEditableLineCount(dwID) + 2);
int iLineIndex = 0;
float fAlpha = 0.0f;
@@ -175,8 +183,15 @@ void CPythonChat::UpdateEditMode(DWORD dwID)
}
iHeight += pChatSet->m_iStep;
pChatLine->Instance.SetPosition(pChatSet->m_ix, pChatSet->m_iy + iHeight);
pChatLine->Instance.SetColor(rColor);
pChatLine->Instance.SetColor(pChatLine->GetColorRef(dwID));
if (pChatSet->m_iAlign == 1)
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::RTL);
else
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::LTR);
pChatLine->Instance.Update();
}
}
@@ -195,8 +210,15 @@ void CPythonChat::UpdateLogMode(DWORD dwID)
TChatLine * pChatLine = (*itor);
iHeight -= pChatSet->m_iStep;
pChatLine->Instance.SetPosition(pChatSet->m_ix, pChatSet->m_iy + iHeight);
pChatLine->Instance.SetColor(pChatLine->GetColorRef(dwID));
if (pChatSet->m_iAlign == 1)
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::RTL);
else
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::LTR);
pChatLine->Instance.Update();
}
}
@@ -251,7 +273,6 @@ void CPythonChat::Render(DWORD dwID)
}
}
void CPythonChat::SetBoardState(DWORD dwID, int iState)
{
TChatSet * pChatSet = GetChatSetPtr(dwID);
@@ -261,6 +282,7 @@ void CPythonChat::SetBoardState(DWORD dwID, int iState)
pChatSet->m_iBoardState = iState;
ArrangeShowingChat(dwID);
}
void CPythonChat::SetPosition(DWORD dwID, int ix, int iy)
{
TChatSet * pChatSet = GetChatSetPtr(dwID);
@@ -270,6 +292,25 @@ void CPythonChat::SetPosition(DWORD dwID, int ix, int iy)
pChatSet->m_ix = ix;
pChatSet->m_iy = iy;
}
void CPythonChat::SetAlign(DWORD dwID, int iAlign)
{
TChatSet* pChatSet = GetChatSetPtr(dwID);
if (!pChatSet)
return;
pChatSet->m_iAlign = (iAlign != 0) ? 1 : 0;
}
void CPythonChat::SetWidth(DWORD dwID, int iWidth)
{
TChatSet* pChatSet = GetChatSetPtr(dwID);
if (!pChatSet)
return;
pChatSet->m_iWidth = iWidth;
}
void CPythonChat::SetHeight(DWORD dwID, int iHeight)
{
TChatSet * pChatSet = GetChatSetPtr(dwID);
@@ -278,6 +319,7 @@ void CPythonChat::SetHeight(DWORD dwID, int iHeight)
pChatSet->m_iHeight = iHeight;
}
void CPythonChat::SetStep(DWORD dwID, int iStep)
{
TChatSet * pChatSet = GetChatSetPtr(dwID);
@@ -286,6 +328,7 @@ void CPythonChat::SetStep(DWORD dwID, int iStep)
pChatSet->m_iStep = iStep;
}
void CPythonChat::ToggleChatMode(DWORD dwID, int iMode)
{
TChatSet * pChatSet = GetChatSetPtr(dwID);
@@ -296,6 +339,7 @@ void CPythonChat::ToggleChatMode(DWORD dwID, int iMode)
// Tracef("ToggleChatMode : %d\n", iMode);
ArrangeShowingChat(dwID);
}
void CPythonChat::EnableChatMode(DWORD dwID, int iMode)
{
TChatSet * pChatSet = GetChatSetPtr(dwID);
@@ -306,6 +350,7 @@ void CPythonChat::EnableChatMode(DWORD dwID, int iMode)
// Tracef("EnableChatMode : %d\n", iMode);
ArrangeShowingChat(dwID);
}
void CPythonChat::DisableChatMode(DWORD dwID, int iMode)
{
TChatSet * pChatSet = GetChatSetPtr(dwID);
@@ -316,6 +361,7 @@ void CPythonChat::DisableChatMode(DWORD dwID, int iMode)
// Tracef("DisableChatMode : %d\n", iMode);
ArrangeShowingChat(dwID);
}
void CPythonChat::SetEndPos(DWORD dwID, float fPos)
{
TChatSet * pChatSet = GetChatSetPtr(dwID);
@@ -452,8 +498,21 @@ void CPythonChat::AppendChat(int iType, const char * c_szChat)
IAbstractApplication& rApp=IAbstractApplication::GetSingleton();
SChatLine * pChatLine = SChatLine::New();
pChatLine->iType = iType;
// Pass chat text as-is to BiDi algorithm
// BuildVisualBidiText_Tagless will detect chat format and handle reordering
pChatLine->Instance.SetValue(c_szChat);
if (IsRTL())
{
// RTL mode: BiDi will handle chat format detection and reordering
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::RTL);
}
else
{
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::LTR);
}
// DEFAULT_FONT
pChatLine->Instance.SetTextPointer(pkDefaultFont);
// END_OF_DEFAULT_FONT
@@ -699,25 +758,30 @@ void CWhisper::SetBoxSize(float fWidth, float fHeight)
void CWhisper::AppendChat(int iType, const char * c_szChat)
{
// DEFAULT_FONT
//static CResource * s_pResource = CResourceManager::Instance().GetResourcePointer(g_strDefaultFontName.c_str());
#if defined(LOCALE_SERVICE_YMIR) || defined(LOCALE_SERVICE_JAPAN) || defined(LOCALE_SERVICE_HONGKONG) || defined(LOCALE_SERVICE_TAIWAN) || defined(LOCALE_SERVICE_NEWCIBN)
CGraphicText* pkDefaultFont = static_cast<CGraphicText*>(DefaultFont_GetResource());
#else
CGraphicText* pkDefaultFont = (iType == CPythonChat::WHISPER_TYPE_GM) ? static_cast<CGraphicText*>(DefaultItalicFont_GetResource()) : static_cast<CGraphicText*>(DefaultFont_GetResource());
#endif
if (!pkDefaultFont)
{
TraceError("CWhisper::AppendChat - CANNOT_FIND_DEFAULT_FONT");
return;
}
// END_OF_DEFAULT_FONT
SChatLine * pChatLine = SChatLine::New();
// Pass chat text as-is to BiDi algorithm
// BuildVisualBidiText_Tagless will detect chat format and handle reordering
pChatLine->Instance.SetValue(c_szChat);
if (IsRTL())
{
// RTL mode: BiDi will handle chat format detection and reordering
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::RTL);
}
else
{
pChatLine->Instance.SetTextDirection(CGraphicTextInstance::ETextDirection::LTR);
}
// DEFAULT_FONT
pChatLine->Instance.SetTextPointer(pkDefaultFont);
// END_OF_DEFAULT_FONT

View File

@@ -129,9 +129,11 @@ class CPythonChat : public CSingleton<CPythonChat>, public IAbstractChat
{
int m_ix;
int m_iy;
int m_iWidth;
int m_iHeight;
int m_iStep;
float m_fEndPos;
int m_iAlign;
int m_iBoardState;
std::vector<int> m_iMode;
@@ -153,8 +155,10 @@ class CPythonChat : public CSingleton<CPythonChat>, public IAbstractChat
m_ix = 0;
m_iy = 0;
m_fEndPos = 1.0f;
m_iWidth = 0;
m_iHeight = 0;
m_iStep = 15;
m_iAlign = 0;
m_iMode.clear();
m_iMode.resize(ms_iChatModeSize, 1);
@@ -182,6 +186,8 @@ class CPythonChat : public CSingleton<CPythonChat>, public IAbstractChat
void SetBoardState(DWORD dwID, int iState);
void SetPosition(DWORD dwID, int ix, int iy);
void SetHeight(DWORD dwID, int iHeight);
void SetWidth(DWORD dwID, int iWidth);
void SetAlign(DWORD dwID, int iAlign);
void SetStep(DWORD dwID, int iStep);
void ToggleChatMode(DWORD dwID, int iMode);
void EnableChatMode(DWORD dwID, int iMode);

View File

@@ -97,6 +97,33 @@ PyObject * chatSetPosition(PyObject* poSelf, PyObject* poArgs)
return Py_BuildNone();
}
PyObject* chatSetAlign(PyObject* poSelf, PyObject* poArgs)
{
int iID;
if (!PyTuple_GetInteger(poArgs, 0, &iID))
return Py_BuildException();
int iAlign;
if (!PyTuple_GetInteger(poArgs, 1, &iAlign))
return Py_BuildException();
CPythonChat::Instance().SetAlign(iID, iAlign);
return Py_BuildNone();
}
PyObject* chatSetWidth(PyObject* poSelf, PyObject* poArgs)
{
int iID;
int iWidth;
if (!PyTuple_GetInteger(poArgs, 0, &iID))
return Py_BadArgument();
if (!PyTuple_GetInteger(poArgs, 1, &iWidth))
return Py_BadArgument();
CPythonChat::Instance().SetWidth((DWORD)iID, iWidth);
return Py_BuildNone();
}
PyObject * chatSetHeight(PyObject* poSelf, PyObject* poArgs)
{
int iID;
@@ -462,6 +489,8 @@ void initChat()
{ "SetBoardState", chatSetBoardState, METH_VARARGS },
{ "SetPosition", chatSetPosition, METH_VARARGS },
{ "SetAlign", chatSetAlign, METH_VARARGS },
{ "SetWidth", chatSetWidth, METH_VARARGS },
{ "SetHeight", chatSetHeight, METH_VARARGS },
{ "SetStep", chatSetStep, METH_VARARGS },
{ "ToggleChatMode", chatToggleChatMode, METH_VARARGS },

View File

@@ -985,19 +985,19 @@ void CPythonEventManager::__InsertLine(TEventSet& rEventSet, BOOL isCenter, int
int textWidth;
int textHeight;
rEventSet.pCurrentTextLine->GetTextSize(&textWidth,&textHeight);
if (GetDefaultCodePage() == CP_1256)
const bool prevRTL = (rEventSet.pCurrentTextLine && rEventSet.pCurrentTextLine->IsRTL());
kLine.ixLocal = prevRTL ? rEventSet.iWidth : 0;
if (iX_pos != 0)
{
kLine.ixLocal = rEventSet.iWidth;
if (iX_pos != 0)
if (prevRTL)
{
kLine.ixLocal -= iX_pos - 20;
kLine.ixLocal -= (iX_pos - 20);
kLine.ixLocal += textWidth / 2;
}
}
else
{
kLine.ixLocal = 0;
if (iX_pos != 0)
else
{
kLine.ixLocal += (iX_pos - 20);
kLine.ixLocal -= textWidth / 2;
@@ -1008,7 +1008,7 @@ void CPythonEventManager::__InsertLine(TEventSet& rEventSet, BOOL isCenter, int
}
kLine.pInstance = rEventSet.pCurrentTextLine;
rEventSet.ScriptTextLineList.push_back(kLine);
__AddSpace(rEventSet, c_fLine_Temp);
__AddSpace(rEventSet, c_fLine_Temp);
}
// DEFAULT_FONT
@@ -1040,16 +1040,8 @@ void CPythonEventManager::__InsertLine(TEventSet& rEventSet, BOOL isCenter, int
}
else
{
if (GetDefaultCodePage() == CP_1256)
{
rEventSet.pCurrentTextLine->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT);
rEventSet.pCurrentTextLine->SetPosition(rEventSet.ix + rEventSet.iWidth, rEventSet.iy + rEventSet.iyLocal);
}
else
{
rEventSet.pCurrentTextLine->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT);
rEventSet.pCurrentTextLine->SetPosition(rEventSet.ix, rEventSet.iy + rEventSet.iyLocal);
}
rEventSet.pCurrentTextLine->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT);
rEventSet.pCurrentTextLine->SetPosition(rEventSet.ix, rEventSet.iy + rEventSet.iyLocal);
}
rEventSet.iCurrentLetter = 0;
@@ -1073,10 +1065,8 @@ void CPythonEventManager::RefreshLinePosition(TEventSet * pEventSet)
}
else
{
if (GetDefaultCodePage() == CP_1256)
ixTextPos = pEventSet->ix+pEventSet->iWidth;
else
ixTextPos = pEventSet->ix;
const bool isRTL = (pEventSet->pCurrentTextLine && pEventSet->pCurrentTextLine->IsRTL());
ixTextPos = isRTL ? (pEventSet->ix + pEventSet->iWidth) : pEventSet->ix;
}
pEventSet->pCurrentTextLine->SetPosition(ixTextPos, pEventSet->iy + pEventSet->iyLocal);
}

View File

@@ -475,7 +475,7 @@ PyObject * guildGetGuildExperience(PyObject * poSelf, PyObject * poArgs)
if (rGuildInfo.dwGuildLevel >= GULID_MAX_LEVEL)
return Py_BuildValue("ii", 0, 0);
unsigned lastExp = LocaleService_GetLastExp(rGuildInfo.dwGuildLevel);
unsigned lastExp = GetGuildLastExp(rGuildInfo.dwGuildLevel);
return Py_BuildValue("ii", rGuildInfo.dwCurrentExperience, lastExp - rGuildInfo.dwCurrentExperience);
}

View File

@@ -68,34 +68,88 @@ void CPythonIME::OnEscape()
// IAbstractApplication::GetSingleton().RunIMEEscapeEvent();
}
bool CPythonIME::OnWM_CHAR( WPARAM wParam, LPARAM lParam )
bool CPythonIME::OnWM_CHAR(WPARAM wParam, LPARAM lParam)
{
unsigned char c = unsigned char(wParam & 0xff);
const wchar_t wc = (wchar_t)wParam;
switch (c)
const bool ctrlDown = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
// Ctrl+<key> combos only when Ctrl is pressed
if (ctrlDown)
{
case VK_RETURN:
OnReturn();
return true;
switch (wc)
{
case 0x01: // Ctrl+A
if (ms_bCaptureInput)
{
SelectAll();
if (ms_pEvent) ms_pEvent->OnUpdate();
return true;
}
return false;
case VK_TAB:
if(ms_bCaptureInput == false)
return 0;
OnTab();
return true;
case 0x1A: // Ctrl+Z
if (ms_bCaptureInput)
{
CIME::Undo();
return true;
}
return false;
case VK_ESCAPE:
if(ms_bCaptureInput == false)
return 0;
OnEscape();
return true;
case 0x03: // Ctrl+C
if (ms_bCaptureInput)
{
CopySelectionToClipboard();
return true;
}
return false;
case 0x16: // Ctrl+V
if (ms_bCaptureInput)
{
PasteTextFromClipBoard();
return true;
}
return false;
case 0x18: // Ctrl+X
if (ms_bCaptureInput)
{
CutSelection();
if (ms_pEvent) ms_pEvent->OnUpdate();
return true;
}
return false;
case 0x19: // Ctrl+Y
if (ms_bCaptureInput)
{
CIME::Redo();
return true;
}
return false;
}
}
return false;
}
void CPythonIME::OnChangeCodePage()
{
IAbstractApplication::GetSingleton().RunIMEChangeCodePage();
// Non-Ctrl special keys (WM_CHAR gives these too)
switch (wc)
{
case VK_RETURN:
OnReturn();
return true;
case VK_TAB:
if (!ms_bCaptureInput) return 0;
OnTab();
return true;
case VK_ESCAPE:
if (!ms_bCaptureInput) return 0;
OnEscape();
return true;
}
return false;
}
void CPythonIME::OnOpenCandidateList()
@@ -117,3 +171,29 @@ void CPythonIME::OnCloseReadingWnd()
{
IAbstractApplication::GetSingleton().RunIMECloseReadingWndEvent();
}
void CPythonIME::SelectAll()
{
CIME::SelectAll();
}
void CPythonIME::DeleteSelection()
{
CIME::DeleteSelection();
}
void CPythonIME::CopySelectionToClipboard()
{
CIME::CopySelectionToClipboard(ms_hWnd);
}
void CPythonIME::CutSelection()
{
CIME::CopySelectionToClipboard(ms_hWnd);
CIME::DeleteSelection();
}
void CPythonIME::PasteTextFromClipBoard()
{
CIME::PasteTextFromClipBoard();
}

View File

@@ -19,6 +19,12 @@ public:
void SetCursorPosition(int iPosition);
void Delete();
void SelectAll();
void DeleteSelection();
void CopySelectionToClipboard();
void CutSelection();
void PasteTextFromClipBoard();
void Create(HWND hWnd);
protected:
@@ -28,9 +34,9 @@ protected:
virtual bool OnWM_CHAR( WPARAM wParam, LPARAM lParam );
virtual void OnUpdate();
virtual void OnChangeCodePage();
virtual void OnOpenCandidateList();
virtual void OnCloseCandidateList();
virtual void OnOpenReadingWnd();
virtual void OnCloseReadingWnd();
};

View File

@@ -57,19 +57,10 @@ PyObject* imeSetText(PyObject* poSelf, PyObject* poArgs)
}
PyObject* imeGetText(PyObject* poSelf, PyObject* poArgs)
{
int bCodePage;
if (!PyTuple_GetInteger(poArgs, 0, &bCodePage))
bCodePage = 0;
std::string strText;
CPythonIME::Instance().GetText(strText, bCodePage ? true : false);
return Py_BuildValue("s", strText.c_str());
}
PyObject* imeGetCodePage(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("i", CPythonIME::Instance().GetCodePage());
std::string strText;
CPythonIME::Instance().GetText(strText);
return Py_BuildValue("s", strText.c_str());
}
PyObject* imeGetCandidateCount(PyObject* poSelf, PyObject* poArgs)
@@ -210,6 +201,25 @@ PyObject* imePasteTextFromClipBoard(PyObject* poSelf, PyObject* poArgs)
return Py_BuildNone();
}
PyObject* imeSelectAll(PyObject* poSelf, PyObject* poArgs)
{
CPythonIME::Instance().SelectAll();
return Py_BuildNone();
}
PyObject* imeCopySelectionToClipboard(PyObject* poSelf, PyObject* poArgs)
{
CPythonIME::Instance().CopySelectionToClipboard();
return Py_BuildNone();
}
PyObject* imeCutSelection(PyObject* poSelf, PyObject* poArgs)
{
CPythonIME::Instance().CopySelectionToClipboard();
CPythonIME::Instance().DeleteSelection();
return Py_BuildNone();
}
PyObject* imeEnablePaste(PyObject* poSelf, PyObject* poArgs)
{
int iFlag;
@@ -254,7 +264,6 @@ void initime()
{ "SetUserMax", imeSetUserMax, METH_VARARGS },
{ "SetText", imeSetText, METH_VARARGS },
{ "GetText", imeGetText, METH_VARARGS },
{ "GetCodePage", imeGetCodePage, METH_VARARGS },
{ "GetCandidateCount", imeGetCandidateCount, METH_VARARGS },
{ "GetCandidate", imeGetCandidate, METH_VARARGS },
{ "GetCandidateSelection", imeGetCandidateSelection, METH_VARARGS },
@@ -280,6 +289,9 @@ void initime()
{ "PasteBackspace", imePasteBackspace, METH_VARARGS },
{ "PasteReturn", imePasteReturn, METH_VARARGS },
{ "PasteTextFromClipBoard", imePasteTextFromClipBoard, METH_VARARGS },
{ "SelectAll", imeSelectAll, METH_VARARGS },
{ "CutSelection", imeCutSelection, METH_VARARGS },
{ "CopySelection", imeCopySelectionToClipboard,METH_VARARGS },
{ "EnablePaste", imeEnablePaste, METH_VARARGS },
{ NULL, NULL, NULL },

View File

@@ -7,6 +7,7 @@
#include "PythonMiniMap.h"
#include "PythonBackground.h"
#include "PythonCharacterManager.h"
#include "PythonNonPlayer.h"
#include "PythonGuild.h"
#include "AbstractPlayer.h"
@@ -812,7 +813,7 @@ void CPythonMiniMap::__LoadAtlasMarkInfo()
// LOCALE
char szAtlasMarkInfoFileName[64+1];
_snprintf(szAtlasMarkInfoFileName, sizeof(szAtlasMarkInfoFileName), "%s/map/%s_point.txt", LocaleService_GetLocalePath(), rkMap.GetName().c_str());
_snprintf(szAtlasMarkInfoFileName, sizeof(szAtlasMarkInfoFileName), "%s/map/%s_point.txt", GetLocalePathCommon(), rkMap.GetName().c_str());
// END_OF_LOCALE
CTokenVectorMap stTokenVectorMap;
@@ -823,8 +824,6 @@ void CPythonMiniMap::__LoadAtlasMarkInfo()
return;
}
const std::string strType[TYPE_COUNT] = { "OPC", "OPCPVP", "OPCPVPSELF", "NPC", "MONSTER", "WARP", "WAYPOINT" };
for (DWORD i = 0; i < stTokenVectorMap.size(); ++i)
{
char szMarkInfoName[32+1];
@@ -835,33 +834,43 @@ void CPythonMiniMap::__LoadAtlasMarkInfo()
const CTokenVector & rVector = stTokenVectorMap[szMarkInfoName];
const std::string & c_rstrType = rVector[0].c_str();
const std::string & c_rstrPositionX = rVector[1].c_str();
const std::string & c_rstrPositionY = rVector[2].c_str();
const std::string & c_rstrText = rVector[3].c_str();
const std::string& c_rstrPositionX = rVector[0].c_str();
const std::string& c_rstrPositionY = rVector[1].c_str();
const std::string& c_rstrVnum = rVector[2].c_str();
const DWORD c_dwVnum = atoi(c_rstrVnum.c_str());
TAtlasMarkInfo aAtlasMarkInfo;
for ( int i = 0; i < TYPE_COUNT; ++i)
const CPythonNonPlayer::TMobTable* c_pMobTable = CPythonNonPlayer::Instance().GetTable(c_dwVnum);
if (c_pMobTable)
{
if (0 == c_rstrType.compare(strType[i]))
aAtlasMarkInfo.m_byType = (BYTE)i;
}
aAtlasMarkInfo.m_fX = atof(c_rstrPositionX.c_str());
aAtlasMarkInfo.m_fY = atof(c_rstrPositionY.c_str());
aAtlasMarkInfo.m_strText = c_rstrText;
TAtlasMarkInfo aAtlasMarkInfo;
aAtlasMarkInfo.m_fX = atof(c_rstrPositionX.c_str());
aAtlasMarkInfo.m_fY = atof(c_rstrPositionY.c_str());
aAtlasMarkInfo.m_strText = c_pMobTable->szLocaleName;
if (c_pMobTable->bType == CActorInstance::TYPE_NPC)
aAtlasMarkInfo.m_byType = TYPE_NPC;
else if (c_pMobTable->bType == CActorInstance::TYPE_WARP)
{
aAtlasMarkInfo.m_byType = TYPE_WARP;
int iPos = aAtlasMarkInfo.m_strText.find(" ");
if (iPos >= 0)
aAtlasMarkInfo.m_strText[iPos] = 0;
aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f;
aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f;
}
else if (c_pMobTable->bType == CActorInstance::TYPE_STONE && c_dwVnum >= 20702 && c_dwVnum <= 20706)
aAtlasMarkInfo.m_byType = TYPE_NPC;
switch(aAtlasMarkInfo.m_byType)
{
aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f;
aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f;
switch (aAtlasMarkInfo.m_byType)
{
case TYPE_NPC:
m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo);
break;
case TYPE_WARP:
m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo);
break;
}
}
}
}

View File

@@ -1,9 +1,7 @@
#include "StdAfx.h"
#include "PythonNetworkStream.h"
//#include "PythonNetworkDatagram.h"
#include "AccountConnector.h"
#include "PythonGuild.h"
#include "Test.h"
#include "AbstractPlayer.h"
@@ -67,11 +65,6 @@ PyObject* netStartGame(PyObject* poSelf, PyObject* poArgs)
return Py_BuildNone();
}
PyObject* netIsTest(PyObject* poSelf, PyObject* poArgs)
{
return Py_BuildValue("i", __IS_TEST_SERVER_MODE__);
}
PyObject* netWarp(PyObject* poSelf, PyObject* poArgs)
{
int nX;
@@ -1695,7 +1688,6 @@ void initnet()
{ "StartGame", netStartGame, METH_VARARGS },
{ "Warp", netWarp, METH_VARARGS },
{ "IsTest", netIsTest, METH_VARARGS },
{ "SetMarkServer", netSetMarkServer, METH_VARARGS },
{ "IsChatInsultIn", netIsChatInsultIn, METH_VARARGS },
{ "IsInsultIn", netIsInsultIn, METH_VARARGS },

View File

@@ -1268,7 +1268,7 @@ void CPythonNetworkStream::__ConvertEmpireText(DWORD dwEmpireID, char* szText)
bool CPythonNetworkStream::RecvChatPacket()
{
TPacketGCChat kChat;
char buf[1024 + 1];
char buf[1024 + 1];
char line[1024 + 1];
if (!Recv(sizeof(kChat), &kChat))
@@ -1280,16 +1280,6 @@ bool CPythonNetworkStream::RecvChatPacket()
return false;
buf[uChatSize]='\0';
// 유럽 아랍 버전 처리
// "이름: 내용" 입력을 "내용: 이름" 순서로 출력하기 위해 탭(0x08)을 넣음
// 탭을 아랍어 기호로 처리해 (영어1) : (영어2) 로 입력되어도 (영어2) : (영어1) 로 출력하게 만든다
if (LocaleService_IsEUROPE() && GetDefaultCodePage() == 1256)
{
char * p = strchr(buf, ':');
if (p && p[1] == ' ')
p[1] = 0x08;
}
if (kChat.type >= CHAT_TYPE_MAX_NUM)
return true;
@@ -4030,7 +4020,6 @@ bool CPythonNetworkStream::RecvWalkModePacket()
bool CPythonNetworkStream::RecvChangeSkillGroupPacket()
{
TPacketGCChangeSkillGroup ChangeSkillGroup;
if (!Recv(sizeof(ChangeSkillGroup), &ChangeSkillGroup))
return false;
@@ -4038,7 +4027,6 @@ bool CPythonNetworkStream::RecvChangeSkillGroupPacket()
CPythonPlayer::Instance().NEW_ClearSkillData();
__RefreshCharacterWindow();
return true;
}
@@ -4164,30 +4152,6 @@ bool CPythonNetworkStream::RecvNPCList()
bool CPythonNetworkStream::__SendCRCReportPacket()
{
/*
DWORD dwProcessCRC = 0;
DWORD dwFileCRC = 0;
CFilename exeFileName;
//LPCVOID c_pvBaseAddress = NULL;
GetExeCRC(dwProcessCRC, dwFileCRC);
CFilename strRootPackFileName = CEterPackManager::Instance().GetRootPacketFileName();
strRootPackFileName.ChangeDosPath();
TPacketCGCRCReport kReportPacket;
kReportPacket.header = HEADER_CG_CRC_REPORT;
kReportPacket.byPackMode = CEterPackManager::Instance().GetSearchMode();
kReportPacket.dwBinaryCRC32 = dwFileCRC;
kReportPacket.dwProcessCRC32 = dwProcessCRC;
kReportPacket.dwRootPackCRC32 = GetFileCRC32(strRootPackFileName.c_str());
if (!Send(sizeof(kReportPacket), &kReportPacket))
Tracef("SendClientReportPacket Error");
return SendSequence();
*/
return true;
}
@@ -4200,29 +4164,17 @@ bool CPythonNetworkStream::SendClientVersionPacket()
filename = CFileNameHelper::NoPath(filename);
CFileNameHelper::ChangeDosPath(filename);
if (LocaleService_IsEUROPE() && false == LocaleService_IsYMIR())
{
TPacketCGClientVersion2 kVersionPacket;
kVersionPacket.header = HEADER_CG_CLIENT_VERSION2;
strncpy(kVersionPacket.filename, filename.c_str(), sizeof(kVersionPacket.filename)-1);
strncpy(kVersionPacket.timestamp, "1215955205", sizeof(kVersionPacket.timestamp)-1); // # python time.time 앞자리
//strncpy(kVersionPacket.timestamp, __TIMESTAMP__, sizeof(kVersionPacket.timestamp)-1); // old_string_ver
//strncpy(kVersionPacket.timestamp, "1218055205", sizeof(kVersionPacket.timestamp)-1); // new_future
//strncpy(kVersionPacket.timestamp, "1214055205", sizeof(kVersionPacket.timestamp)-1); // old_past
TPacketCGClientVersion kVersionPacket{};
kVersionPacket.header = HEADER_CG_CLIENT_VERSION;
if (!Send(sizeof(kVersionPacket), &kVersionPacket))
Tracef("SendClientReportPacket Error");
}
else
{
TPacketCGClientVersion kVersionPacket;
kVersionPacket.header = HEADER_CG_CLIENT_VERSION;
strncpy(kVersionPacket.filename, filename.c_str(), sizeof(kVersionPacket.filename)-1);
strncpy(kVersionPacket.timestamp, __TIMESTAMP__, sizeof(kVersionPacket.timestamp)-1);
strncpy(kVersionPacket.filename, filename.c_str(), sizeof(kVersionPacket.filename) - 1);
kVersionPacket.filename[sizeof(kVersionPacket.filename) - 1] = '\0';
snprintf(kVersionPacket.timestamp, sizeof(kVersionPacket.timestamp), "%u", 1215955205u);
if (!Send(sizeof(kVersionPacket), &kVersionPacket))
Tracef("SendClientReportPacket Error");
if (!Send(sizeof(kVersionPacket), &kVersionPacket))
Tracef("SendClientReportPacket Error");
}
return SendSequence();
}

View File

@@ -171,7 +171,7 @@ void CPythonNetworkStream::SetLoadingPhase()
Tracen("## Network - Loading Phase ##");
Tracen("");
m_strPhase = "Loading";
m_strPhase = "Loading";
m_dwChangingPhaseTime = ELTimer_GetMSec();
m_phaseProcessFunc.Set(this, &CPythonNetworkStream::LoadingPhase);
@@ -292,8 +292,8 @@ bool CPythonNetworkStream::RecvMainCharacter4_BGM_VOL()
}
static std::string gs_fieldMusic_fileName;
static float gs_fieldMusic_volume = 1.0f / 5.0f * 0.1f;
static std::string gs_fieldMusic_fileName;
static float gs_fieldMusic_volume = 1.0f / 5.0f * 0.1f;
void CPythonNetworkStream::__SetFieldMusicFileName(const char* musicName)
{

View File

@@ -1,7 +1,6 @@
#include "StdAfx.h"
#include "PythonNetworkStream.h"
#include "Packet.h"
#include "Test.h"
#include "AccountConnector.h"
// Login ---------------------------------------------------------------------------
@@ -69,7 +68,7 @@ void CPythonNetworkStream::LoginPhase()
void CPythonNetworkStream::SetLoginPhase()
{
const char* key = LocaleService_GetSecurityKey();
const char* key = GetSecurityKey();
#ifndef _IMPROVED_PACKET_ENCRYPTION_
SetSecurityMode(true, key);
#endif
@@ -81,7 +80,7 @@ void CPythonNetworkStream::SetLoginPhase()
Tracen("## Network - Login Phase ##");
Tracen("");
m_strPhase = "Login";
m_strPhase = "Login";
m_phaseProcessFunc.Set(this, &CPythonNetworkStream::LoginPhase);
m_phaseLeaveFunc.Set(this, &CPythonNetworkStream::__LeaveLoginPhase);
@@ -133,8 +132,8 @@ bool CPythonNetworkStream::__RecvLoginSuccessPacket3()
TPacketGCLoginSuccess3 kPacketLoginSuccess;
if (!Recv(sizeof(kPacketLoginSuccess), &kPacketLoginSuccess))
return false;
return false;
for (int i = 0; i<PLAYER_PER_ACCOUNT3; ++i)
{
m_akSimplePlayerInfo[i]=kPacketLoginSuccess.akSimplePlayerInformation[i];
@@ -161,8 +160,8 @@ bool CPythonNetworkStream::__RecvLoginSuccessPacket4()
TPacketGCLoginSuccess4 kPacketLoginSuccess;
if (!Recv(sizeof(kPacketLoginSuccess), &kPacketLoginSuccess))
return false;
return false;
for (int i = 0; i<PLAYER_PER_ACCOUNT4; ++i)
{
m_akSimplePlayerInfo[i]=kPacketLoginSuccess.akSimplePlayerInformation[i];
@@ -171,20 +170,19 @@ bool CPythonNetworkStream::__RecvLoginSuccessPacket4()
}
m_kMarkAuth.m_dwHandle=kPacketLoginSuccess.handle;
m_kMarkAuth.m_dwRandomKey=kPacketLoginSuccess.random_key;
m_kMarkAuth.m_dwRandomKey=kPacketLoginSuccess.random_key;
if (__DirectEnterMode_IsSet())
{
}
else
{
PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_SELECT], "Refresh", Py_BuildValue("()"));
PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_SELECT], "Refresh", Py_BuildValue("()"));
}
return true;
}
void CPythonNetworkStream::OnConnectFailure()
{
if (__DirectEnterMode_IsSet())
@@ -197,7 +195,6 @@ void CPythonNetworkStream::OnConnectFailure()
}
}
bool CPythonNetworkStream::__RecvLoginFailurePacket()
{
TPacketGCLoginFailure packet_failure;

View File

@@ -369,22 +369,12 @@ DWORD CPythonPlayer::__GetTotalAtk(DWORD dwWeaponPower, DWORD dwRefineBonus)
DWORD dwLvAtk=__GetLevelAtk();
DWORD dwStAtk=__GetStatAtk();
/////
DWORD dwWepAtk;
DWORD dwTotalAtk;
DWORD dwTotalAtk;
if (LocaleService_IsCHEONMA())
{
dwWepAtk = __GetWeaponAtk(dwWeaponPower+dwRefineBonus);
dwTotalAtk = dwLvAtk+(dwStAtk+dwWepAtk)*(GetStatus(POINT_DX)+210)/300;
}
else
{
int hr = __GetHitRate();
dwWepAtk = __GetWeaponAtk(dwWeaponPower+dwRefineBonus);
dwTotalAtk = dwLvAtk+(dwStAtk+dwWepAtk)*hr/100;
}
int hr = __GetHitRate();
dwWepAtk = __GetWeaponAtk(dwWeaponPower+dwRefineBonus);
dwTotalAtk = dwLvAtk+(dwStAtk+dwWepAtk)*hr/100;
return dwTotalAtk;
}
@@ -392,16 +382,7 @@ DWORD CPythonPlayer::__GetTotalAtk(DWORD dwWeaponPower, DWORD dwRefineBonus)
DWORD CPythonPlayer::__GetHitRate()
{
int src = 0;
if (LocaleService_IsCHEONMA())
{
src = GetStatus(POINT_DX);
}
else
{
src = (GetStatus(POINT_DX) * 4 + GetStatus(POINT_LEVEL) * 2)/6;
}
src = (GetStatus(POINT_DX) * 4 + GetStatus(POINT_LEVEL) * 2)/6;
return 100*(std::min(90, src)+210)/300;
}
@@ -1059,7 +1040,6 @@ void CPythonPlayer::SetSkillLevel(DWORD dwSlotIndex, DWORD dwSkillLevel)
void CPythonPlayer::SetSkillLevel_(DWORD dwSkillIndex, DWORD dwSkillGrade, DWORD dwSkillLevel)
{
DWORD dwSlotIndex;
if (!GetSkillSlotIndex(dwSkillIndex, &dwSlotIndex))
return;
@@ -1071,34 +1051,33 @@ void CPythonPlayer::SetSkillLevel_(DWORD dwSkillIndex, DWORD dwSkillGrade, DWORD
case 0:
m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade;
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel;
break;
case 1:
m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade;
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel - 20 + 1;
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-20+1;
break;
case 2:
m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade;
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel - 30 + 1;
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-30+1;
break;
case 3:
m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade;
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel - 40 + 1;
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-40+1;
break;
}
const DWORD SKILL_MAX_LEVEL = 40;
if (dwSkillLevel > SKILL_MAX_LEVEL)
if (dwSkillLevel>SKILL_MAX_LEVEL)
{
m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage = 0.0f;
m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage = 0.0f;
TraceError("CPythonPlayer::SetSkillLevel(SlotIndex=%d, SkillLevel=%d)", dwSlotIndex, dwSkillLevel);
return;
}
@@ -1106,9 +1085,10 @@ void CPythonPlayer::SetSkillLevel_(DWORD dwSkillIndex, DWORD dwSkillGrade, DWORD
{
ResetSkillCoolTimeForSlot(dwSlotIndex);
}
m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage = LocaleService_GetSkillPower(dwSkillLevel) / 100.0f;
m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage = LocaleService_GetSkillPower(dwSkillLevel + 1) / 100.0f;
m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage = GetSkillPower(dwSkillLevel)/100.0f;
m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage = GetSkillPower(dwSkillLevel+1)/100.0f;
}
void CPythonPlayer::SetSkillCoolTime(DWORD dwSkillIndex)

View File

@@ -2,6 +2,8 @@
#include "PythonPlayer.h"
#include "PythonApplication.h"
#include <utf8.h>
extern const DWORD c_iSkillIndex_Tongsol = 121;
extern const DWORD c_iSkillIndex_Combo = 122;
extern const DWORD c_iSkillIndex_Fishing = 123;
@@ -1036,19 +1038,22 @@ PyObject * playerGetItemLink(PyObject * poSelf, PyObject * poArgs)
switch (PyTuple_Size(poArgs))
{
case 1:
if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell))
case 1:
if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell))
return Py_BuildException();
break;
case 2:
if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type))
return Py_BuildException();
if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell))
return Py_BuildException();
break;
default:
return Py_BuildException();
break;
case 2:
if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type))
return Py_BuildException();
if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell))
return Py_BuildException();
break;
default:
return Py_BuildException();
}
const TItemData * pPlayerItem = CPythonPlayer::Instance().GetItemData(Cell);
CItemData * pItemData = NULL;
char buf[1024];
@@ -1060,31 +1065,21 @@ PyObject * playerGetItemLink(PyObject * poSelf, PyObject * poArgs)
bool isAttr = false;
len = snprintf(itemlink, sizeof(itemlink), "item:%x:%x:%x:%x:%x",
pPlayerItem->vnum, pPlayerItem->flags,
pPlayerItem->alSockets[0], pPlayerItem->alSockets[1], pPlayerItem->alSockets[2]);
pPlayerItem->vnum, pPlayerItem->flags, pPlayerItem->alSockets[0], pPlayerItem->alSockets[1], pPlayerItem->alSockets[2]);
for (int i = 0; i < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++i)
if (pPlayerItem->aAttr[i].bType != 0)
{
len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%d",
pPlayerItem->aAttr[i].bType, pPlayerItem->aAttr[i].sValue);
len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%d", pPlayerItem->aAttr[i].bType, pPlayerItem->aAttr[i].sValue);
isAttr = true;
}
const std::string wc_szName = pItemData->GetName();
if( GetDefaultCodePage() == CP_ARABIC ) {
if (isAttr)
//"item:번호:플래그:소켓0:소켓1:소켓2"
snprintf(buf, sizeof(buf), " |h|r[%s]|cffffc700|H%s|h", pItemData->GetName(), itemlink);
else
snprintf(buf, sizeof(buf), " |h|r[%s]|cfff1e6c0|H%s|h", pItemData->GetName(), itemlink);
} else {
if (isAttr)
//"item:번호:플래그:소켓0:소켓1:소켓2"
snprintf(buf, sizeof(buf), "|cffffc700|H%s|h[%s]|h|r", itemlink, pItemData->GetName());
else
snprintf(buf, sizeof(buf), "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, pItemData->GetName());
}
if (isAttr)
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "|cffffc700|H%s|h[%s]|h|r", itemlink, wc_szName.c_str());
else
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, wc_szName.c_str());
}
else
buf[0] = '\0';

View File

@@ -164,7 +164,7 @@ bool CPythonSkill::RegisterSkillTable(const char * c_szFileName)
rSkillData.byMaxLevel = maxLevel;
}
const std::string & c_strLevelLimit = TokenVector[TABLE_TOKEN_TYPE_LEVEL_LIMIT];
const std::string & c_strLevelLimit = TokenVector[TABLE_TOKEN_TYPE_LEVEL_LIMIT];
if (!c_strLevelLimit.empty())
{
int levelLimit = atoi(c_strLevelLimit.c_str());
@@ -174,7 +174,7 @@ bool CPythonSkill::RegisterSkillTable(const char * c_szFileName)
const std::string & c_strPointPoly = TokenVector[TABLE_TOKEN_TYPE_POINT_POLY];
// OVERWRITE_SKILLPROTO_POLY
bool USE_SKILL_PROTO = LocaleService_IsCHEONMA() ? false : true;
bool USE_SKILL_PROTO = true;
switch (iVnum)
{
@@ -192,12 +192,12 @@ bool CPythonSkill::RegisterSkillTable(const char * c_szFileName)
USE_SKILL_PROTO = false;
break;
}
if (!rSkillData.AffectDataVector.empty() && USE_SKILL_PROTO)
{
{
TAffectData& affect = rSkillData.AffectDataVector[0];
if (strstr(c_strPointPoly.c_str(), "atk") != NULL ||
if (strstr(c_strPointPoly.c_str(), "atk") != NULL ||
strstr(c_strPointPoly.c_str(), "mwep") != NULL ||
strstr(c_strPointPoly.c_str(), "number") != NULL)
{
@@ -222,22 +222,21 @@ bool CPythonSkill::RegisterSkillTable(const char * c_szFileName)
string_replace_word(src_poly_atk.c_str(), src_poly_atk.length(),
"mwep", 4, "maxmwep", 7, affect.strAffectMaxFormula);
// END_OF_MAX
switch (iVnum)
{
case 1: // 삼연참
case 1:
affect.strAffectMinFormula += "* 3";
affect.strAffectMaxFormula += "* 3";
break;
break;
}
}
else
{
affect.strAffectMinFormula = c_strPointPoly;
affect.strAffectMaxFormula = "";
}
}
}
}
// END_OF_OVERWRITE_SKILLPROTO_POLY
}
@@ -609,7 +608,7 @@ bool CPythonSkill::RegisterSkill(DWORD dwSkillIndex, const char * c_szFileName)
{
char szName[256];
sprintf(szName, "%dname", LocaleService_GetCodePage());
strncpy_s(szName, "name", _TRUNCATE);
if (!TextFileLoader.GetTokenString(szName, &SkillData.strName))
if (!TextFileLoader.GetTokenString("name", &SkillData.strName))
{
@@ -620,7 +619,7 @@ bool CPythonSkill::RegisterSkill(DWORD dwSkillIndex, const char * c_szFileName)
{
char szName[256];
sprintf(szName, "%ddescription", LocaleService_GetCodePage());
strncpy_s(szName, "description", _TRUNCATE);
if (!TextFileLoader.GetTokenString(szName, &SkillData.strDescription))
TextFileLoader.GetTokenString("description", &SkillData.strDescription);
}
@@ -635,7 +634,7 @@ bool CPythonSkill::RegisterSkill(DWORD dwSkillIndex, const char * c_szFileName)
CTokenVector * pConditionDataVector;
char szConditionData[256];
sprintf(szConditionData, "%dconditiondata", LocaleService_GetCodePage());
strncpy_s(szConditionData, "conditiondata", _TRUNCATE);
bool isConditionData=true;
if (!TextFileLoader.GetTokenVector(szConditionData, &pConditionDataVector))
@@ -658,7 +657,7 @@ bool CPythonSkill::RegisterSkill(DWORD dwSkillIndex, const char * c_szFileName)
CTokenVector * pAffectDataVector;
char szAffectData[256];
sprintf(szAffectData, "%daffectdata", LocaleService_GetCodePage());
strncpy_s(szAffectData, "affectdata", _TRUNCATE);
bool isAffectData=true;
if (!TextFileLoader.GetTokenVector(szAffectData, &pAffectDataVector))
@@ -683,7 +682,7 @@ bool CPythonSkill::RegisterSkill(DWORD dwSkillIndex, const char * c_szFileName)
CTokenVector * pGradeDataVector;
char szGradeData[256];
sprintf(szGradeData, "%dgradedata", LocaleService_GetCodePage());
strncpy_s(szGradeData, "gradedata", _TRUNCATE);
if (TextFileLoader.GetTokenVector(szGradeData, &pGradeDataVector))
{
@@ -1280,68 +1279,59 @@ float CPythonSkill::SSkillData::ProcessFormula(CPoly * pPoly, float fSkillLevel,
return pPoly->Eval();
}
const char * CPythonSkill::SSkillData::GetAffectDescription(DWORD dwIndex, float fSkillLevel)
static void ReplaceFirst(std::string& s, const char* needle, const std::string& repl)
{
size_t pos = s.find(needle);
if (pos != std::string::npos)
s.replace(pos, strlen(needle), repl);
}
const char* CPythonSkill::SSkillData::GetAffectDescription(DWORD dwIndex, float fSkillLevel)
{
if (dwIndex >= AffectDataVector.size())
return NULL;
const std::string & c_rstrAffectDescription = AffectDataVector[dwIndex].strAffectDescription;
const std::string & c_rstrAffectMinFormula = AffectDataVector[dwIndex].strAffectMinFormula;
const std::string & c_rstrAffectMaxFormula = AffectDataVector[dwIndex].strAffectMaxFormula;
const std::string& desc = AffectDataVector[dwIndex].strAffectDescription;
const std::string& minF = AffectDataVector[dwIndex].strAffectMinFormula;
const std::string& maxF = AffectDataVector[dwIndex].strAffectMaxFormula;
CPoly minPoly;
CPoly maxPoly;
minPoly.SetStr(c_rstrAffectMinFormula.c_str());
maxPoly.SetStr(c_rstrAffectMaxFormula.c_str());
// OVERWRITE_SKILLPROTO_POLY
minPoly.SetStr(minF.c_str());
maxPoly.SetStr(maxF.c_str());
float fMinValue = ProcessFormula(&minPoly, fSkillLevel);
float fMaxValue = ProcessFormula(&maxPoly, fSkillLevel);
if (fMinValue < 0.0)
fMinValue = - fMinValue;
if (fMaxValue < 0.0)
fMaxValue = - fMaxValue;
if (fMinValue < 0.0f) fMinValue = -fMinValue;
if (fMaxValue < 0.0f) fMaxValue = -fMaxValue;
if (CP_ARABIC == ::GetDefaultCodePage())
const bool wantsInt = (desc.find("%.0f") != std::string::npos);
if (wantsInt)
{
// #0000870: [M2AE] 한국어 모드일때 특정 아랍어 문장에서 크래쉬 발생
static std::string strDescription;
strDescription = c_rstrAffectDescription;
int first = strDescription.find("%.0f");
if (first >= 0)
{
fMinValue = floorf(fMinValue);
fMinValue = floorf(fMinValue);
fMaxValue = floorf(fMaxValue);
}
char szMinValue[256];
_snprintf(szMinValue, sizeof(szMinValue), "%.0f", fMinValue);
strDescription.replace(first, 4, szMinValue);
int second = strDescription.find("%.0f", first);
if (second >= 0)
{
fMaxValue = floorf(fMaxValue);
char szMaxValue[256];
_snprintf(szMaxValue, sizeof(szMaxValue), "%.0f", fMaxValue);
strDescription.replace(second, 4, szMaxValue);
}
}
return strDescription.c_str();
char szMin[64], szMax[64];
if (wantsInt)
{
_snprintf(szMin, sizeof(szMin), "%.0f", fMinValue);
_snprintf(szMax, sizeof(szMax), "%.0f", fMaxValue);
}
else
{
if (strstr(c_rstrAffectDescription.c_str(), "%.0f"))
{
fMinValue = floorf(fMinValue);
fMaxValue = floorf(fMaxValue);
}
static char szDescription[64+1];
_snprintf(szDescription, sizeof(szDescription), c_rstrAffectDescription.c_str(), fMinValue, fMaxValue);
return szDescription;
_snprintf(szMin, sizeof(szMin), "%.2f", fMinValue);
_snprintf(szMax, sizeof(szMax), "%.2f", fMaxValue);
}
static std::string out;
out = desc;
ReplaceFirst(out, "%.0f", szMin);
ReplaceFirst(out, "%.0f", szMax);
return out.c_str();
}
DWORD CPythonSkill::SSkillData::GetSkillCoolTime(float fSkillPoint)

View File

@@ -10,6 +10,8 @@
#include "Locale.h"
#include "MarkManager.h"
#include <utf8.h>
const D3DXCOLOR c_TextTail_Player_Color = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
const D3DXCOLOR c_TextTail_Monster_Color = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
const D3DXCOLOR c_TextTail_Item_Color = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
@@ -211,113 +213,46 @@ void CPythonTextTail::ArrangeTextTail()
for (itor = m_CharacterTextTailList.begin(); itor != m_CharacterTextTailList.end(); ++itor)
{
TTextTail * pTextTail = *itor;
TTextTail* pTextTail = *itor;
float fxAdd = 0.0f;
// Mark 위치 업데이트
CGraphicMarkInstance * pMarkInstance = pTextTail->pMarkInstance;
CGraphicTextInstance * pGuildNameInstance = pTextTail->pGuildNameTextInstance;
CGraphicMarkInstance* pMarkInstance = pTextTail->pMarkInstance;
CGraphicTextInstance* pGuildNameInstance = pTextTail->pGuildNameTextInstance;
if (pMarkInstance && pGuildNameInstance)
{
int iWidth, iHeight;
int iImageHalfSize = pMarkInstance->GetWidth()/2 + c_fxMarkPosition;
int iImageHalfSize = pMarkInstance->GetWidth() / 2 + c_fxMarkPosition;
pGuildNameInstance->GetTextSize(&iWidth, &iHeight);
pMarkInstance->SetPosition(pTextTail->x - iWidth/2 - iImageHalfSize, pTextTail->y - c_fyMarkPosition);
pMarkInstance->SetPosition(pTextTail->x - iWidth / 2 - iImageHalfSize, pTextTail->y - c_fyMarkPosition);
pGuildNameInstance->SetPosition(pTextTail->x + iImageHalfSize, pTextTail->y - c_fyGuildNamePosition, pTextTail->z);
pGuildNameInstance->Update();
}
int iNameWidth, iNameHeight;
// Title & Name refactor
int iNameWidth = 0, iNameHeight = 0;
pTextTail->pTextInstance->GetTextSize(&iNameWidth, &iNameHeight);
// Title 위치 업데이트
CGraphicTextInstance * pTitle = pTextTail->pTitleTextInstance;
if (pTitle)
{
int iTitleWidth, iTitleHeight;
pTitle->GetTextSize(&iTitleWidth, &iTitleHeight);
const float fxAdd = 4.0f;
fxAdd = 8.0f;
float nameShift = 0.0f;
if (pTextTail->pTitleTextInstance)
nameShift = 1.0f;
else if (pTextTail->pLevelTextInstance)
nameShift = 5.0f;
if (LocaleService_IsEUROPE()) // 독일어는 명칭이 길어 오른정렬
{
if( GetDefaultCodePage() == CP_ARABIC )
{
pTitle->SetPosition(pTextTail->x - (iNameWidth / 2) - iTitleWidth - 4.0f, pTextTail->y, pTextTail->z);
}
else
{
// pTitle->SetPosition(pTextTail->x - (iNameWidth / 2), pTextTail->y, pTextTail->z);
pTitle->SetPosition(pTextTail->x - ((iNameWidth / 2)-4.0f), pTextTail->y, pTextTail->z); // Space between level and alignment
}
}
else
{
pTitle->SetPosition(pTextTail->x - (iNameWidth / 2) - fxAdd, pTextTail->y, pTextTail->z);
}
pTitle->Update();
float nameX = floorf((pTextTail->x + nameShift) + 0.5f);
float nameY = floorf(pTextTail->y + 0.5f);
// Level 위치 업데이트
CGraphicTextInstance * pLevel = pTextTail->pLevelTextInstance;
if (pLevel)
{
int iLevelWidth, iLevelHeight;
pLevel->GetTextSize(&iLevelWidth, &iLevelHeight);
if (LocaleService_IsEUROPE()) // 독일어는 명칭이 길어 오른정렬
{
if( GetDefaultCodePage() == CP_ARABIC )
{
pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - iLevelWidth - iTitleWidth - 8.0f, pTextTail->y, pTextTail->z);
}
else
{
pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - iTitleWidth, pTextTail->y, pTextTail->z);
}
}
else
{
pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - fxAdd - iTitleWidth, pTextTail->y, pTextTail->z);
}
const float nameLeftEdge = pTextTail->x - (iNameWidth / 2.0f);
float cursor = nameLeftEdge - fxAdd;
pLevel->Update();
}
}
else
{
fxAdd = 4.0f;
// [Level] [Title] Name - LTR.
// It can be set for RTL - Name [Title] [Level] by adding the required check.
cursor = TextTailBiDi(pTextTail->pTitleTextInstance, cursor, nameY, pTextTail->z, fxAdd, EPlaceDir::Left);
cursor = TextTailBiDi(pTextTail->pLevelTextInstance, cursor, nameY, pTextTail->z, fxAdd, EPlaceDir::Left);
// Level 위치 업데이트
CGraphicTextInstance * pLevel = pTextTail->pLevelTextInstance;
if (pLevel)
{
int iLevelWidth, iLevelHeight;
pLevel->GetTextSize(&iLevelWidth, &iLevelHeight);
if (LocaleService_IsEUROPE()) // 독일어는 명칭이 길어 오른정렬
{
if( GetDefaultCodePage() == CP_ARABIC )
{
pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - iLevelWidth - 4.0f, pTextTail->y, pTextTail->z);
}
else
{
pLevel->SetPosition(pTextTail->x - (iNameWidth / 2), pTextTail->y, pTextTail->z);
}
}
else
{
pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - fxAdd, pTextTail->y, pTextTail->z);
}
pLevel->Update();
}
}
pTextTail->pTextInstance->SetColor(pTextTail->Color.r, pTextTail->Color.g, pTextTail->Color.b);
pTextTail->pTextInstance->SetPosition(pTextTail->x + fxAdd, pTextTail->y, pTextTail->z);
pTextTail->pTextInstance->SetPosition(nameX, nameY, pTextTail->z);
pTextTail->pTextInstance->Update();
}
@@ -721,10 +656,6 @@ void CPythonTextTail::SetItemTextTailOwner(DWORD dwVID, const char * c_szName)
}
std::string strName = c_szName;
static const std::string & strOwnership = ApplicationStringTable_GetString(IDS_POSSESSIVE_MORPHENE) == "" ? "'s" : ApplicationStringTable_GetString(IDS_POSSESSIVE_MORPHENE);
strName += strOwnership;
pTextTail->pOwnerTextInstance->SetTextPointer(ms_pFont);
pTextTail->pOwnerTextInstance->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER);
pTextTail->pOwnerTextInstance->SetValue(strName.c_str());
@@ -733,10 +664,10 @@ void CPythonTextTail::SetItemTextTailOwner(DWORD dwVID, const char * c_szName)
int xOwnerSize, yOwnerSize;
pTextTail->pOwnerTextInstance->GetTextSize(&xOwnerSize, &yOwnerSize);
pTextTail->yStart = -2.0f;
pTextTail->yEnd += float(yOwnerSize + 4);
pTextTail->xStart = fMIN(pTextTail->xStart, float(-xOwnerSize / 2 - 1));
pTextTail->xEnd = fMAX(pTextTail->xEnd, float(xOwnerSize / 2 + 1));
pTextTail->yStart = -2.0f;
pTextTail->yEnd += float(yOwnerSize + 4);
pTextTail->xStart = fMIN(pTextTail->xStart, float(-xOwnerSize / 2 - 1));
pTextTail->xEnd = fMAX(pTextTail->xEnd, float(xOwnerSize / 2 + 1));
}
else
{
@@ -748,10 +679,10 @@ void CPythonTextTail::SetItemTextTailOwner(DWORD dwVID, const char * c_szName)
int xSize, ySize;
pTextTail->pTextInstance->GetTextSize(&xSize, &ySize);
pTextTail->xStart = (float) (-xSize / 2 - 2);
pTextTail->yStart = -2.0f;
pTextTail->xEnd = (float) (xSize / 2 + 2);
pTextTail->yEnd = (float) ySize;
pTextTail->xStart = (float) (-xSize / 2 - 2);
pTextTail->yStart = -2.0f;
pTextTail->xEnd = (float) (xSize / 2 + 2);
pTextTail->yEnd = (float) ySize;
}
}
@@ -906,11 +837,7 @@ void CPythonTextTail::AttachTitle(DWORD dwVID, const char * c_szName, const D3DX
prTitle = CGraphicTextInstance::New();
prTitle->SetTextPointer(ms_pFont);
prTitle->SetOutline(true);
if (LocaleService_IsEUROPE())
prTitle->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_RIGHT);
else
prTitle->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER);
prTitle->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT);
prTitle->SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM);
}
@@ -960,7 +887,7 @@ void CPythonTextTail::AttachLevel(DWORD dwVID, const char * c_szText, const D3DX
prLevel->SetTextPointer(ms_pFont);
prLevel->SetOutline(true);
prLevel->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_RIGHT);
prLevel->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT);
prLevel->SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM);
}

View File

@@ -23,23 +23,16 @@
#endif
#include <dshow.h>
#include "Locale.h"
#include "GameType.h"
extern DWORD __DEFAULT_CODE_PAGE__;
#define APP_NAME "Metin 2"
#define APP_NAME "Metin 2"
enum
{
POINT_MAX_NUM = 255,
POINT_MAX_NUM = 255,
CHARACTER_NAME_MAX_LEN = 24,
#if defined(LOCALE_SERVICE_JAPAN)
PLAYER_NAME_MAX_LEN = 16,
#else
PLAYER_NAME_MAX_LEN = 12,
#endif
};
void initudp();
@@ -73,11 +66,3 @@ void initquest();
void initsafebox();
void initguild();
void initMessenger();
extern const std::string& ApplicationStringTable_GetString(DWORD dwID);
extern const std::string& ApplicationStringTable_GetString(DWORD dwID, LPCSTR szKey);
extern const char* ApplicationStringTable_GetStringz(DWORD dwID);
extern const char* ApplicationStringTable_GetStringz(DWORD dwID, LPCSTR szKey);
extern void ApplicationSetErrorString(const char* szErrorString);

View File

@@ -1,3 +0,0 @@
#pragma once
extern bool __IS_TEST_SERVER_MODE__;

View File

@@ -13,21 +13,24 @@
#include "EterBase/lzo.h"
#include "PackLib/PackManager.h"
#include <filesystem>
#include <format>
extern "C" {
extern int _fltused;
volatile int _AVOID_FLOATING_POINT_LIBRARY_BUG = _fltused;
};
extern "C" { FILE __iob_func[3] = { *stdin,*stdout,*stderr }; }
#include <stdlib.h>
#include <utf8.h>
extern "C" {
extern int _fltused;
FILE __iob_func[3] = { *stdin, *stdout, *stderr };
volatile int _AVOID_FLOATING_POINT_LIBRARY_BUG = _fltused;
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
};
#pragma comment(linker, "/NODEFAULTLIB:libci.lib")
#include <stdlib.h>
bool __IS_TEST_SERVER_MODE__=false;
extern bool SetDefaultCodePage(DWORD codePage);
int Setup(LPSTR lpCmdLine);
static const char * sc_apszPythonLibraryFilenames[] =
{
"UserDict.pyc",
@@ -44,98 +47,30 @@ static const char * sc_apszPythonLibraryFilenames[] =
"\n",
};
char gs_szErrorString[512] = "";
void ApplicationSetErrorString(const char* szErrorString)
{
strcpy(gs_szErrorString, szErrorString);
}
bool CheckPythonLibraryFilenames()
{
for (int i = 0; *sc_apszPythonLibraryFilenames[i] != '\n'; ++i)
{
std::string stFilename = "lib\\";
stFilename += sc_apszPythonLibraryFilenames[i];
std::string stFilenameUtf8 = "lib\\";
stFilenameUtf8 += sc_apszPythonLibraryFilenames[i];
if (_access(stFilename.c_str(), 0) != 0)
std::wstring stFilenameW = Utf8ToWide(stFilenameUtf8);
// Check existence
if (GetFileAttributesW(stFilenameW.c_str()) == INVALID_FILE_ATTRIBUTES)
{
return false;
}
MoveFile(stFilename.c_str(), stFilename.c_str());
// Keep original behavior (forces Windows path normalization)
MoveFileW(stFilenameW.c_str(), stFilenameW.c_str());
}
return true;
}
struct ApplicationStringTable
{
HINSTANCE m_hInstance;
std::map<DWORD, std::string> m_kMap_dwID_stLocale;
} gs_kAppStrTable;
void ApplicationStringTable_Initialize(HINSTANCE hInstance)
{
gs_kAppStrTable.m_hInstance=hInstance;
}
const std::string& ApplicationStringTable_GetString(DWORD dwID, LPCSTR szKey)
{
char szBuffer[512];
char szIniFileName[256];
char szLocale[256];
::GetCurrentDirectory(sizeof(szIniFileName), szIniFileName);
if(szIniFileName[lstrlen(szIniFileName)-1] != '\\')
strcat(szIniFileName, "\\");
strcat(szIniFileName, "metin2client.dat");
strcpy(szLocale, LocaleService_GetLocalePath());
if(strnicmp(szLocale, "locale/", strlen("locale/")) == 0)
strcpy(szLocale, LocaleService_GetLocalePath() + strlen("locale/"));
::GetPrivateProfileString(szLocale, szKey, NULL, szBuffer, sizeof(szBuffer)-1, szIniFileName);
if(szBuffer[0] == '\0')
LoadString(gs_kAppStrTable.m_hInstance, dwID, szBuffer, sizeof(szBuffer)-1);
if(szBuffer[0] == '\0')
::GetPrivateProfileString("en", szKey, NULL, szBuffer, sizeof(szBuffer)-1, szIniFileName);
if(szBuffer[0] == '\0')
strcpy(szBuffer, szKey);
std::string& rstLocale=gs_kAppStrTable.m_kMap_dwID_stLocale[dwID];
rstLocale=szBuffer;
return rstLocale;
}
const std::string& ApplicationStringTable_GetString(DWORD dwID)
{
char szBuffer[512];
LoadString(gs_kAppStrTable.m_hInstance, dwID, szBuffer, sizeof(szBuffer)-1);
std::string& rstLocale=gs_kAppStrTable.m_kMap_dwID_stLocale[dwID];
rstLocale=szBuffer;
return rstLocale;
}
const char* ApplicationStringTable_GetStringz(DWORD dwID, LPCSTR szKey)
{
return ApplicationStringTable_GetString(dwID, szKey).c_str();
}
const char* ApplicationStringTable_GetStringz(DWORD dwID)
{
return ApplicationStringTable_GetString(dwID).c_str();
}
////////////////////////////////////////////
int Setup(LPSTR lpCmdLine); // Internal function forward
bool PackInitialize(const char * c_pszFolder)
{
NANOBEGIN
if (_access(c_pszFolder, 0) != 0)
return false;
@@ -225,28 +160,7 @@ bool PackInitialize(const char * c_pszFolder)
"sound_m",
"sound2",
"bgm",
"locale_ca",
"locale_ae",
"locale_de",
"locale_es",
"locale_fr",
"locale_gr",
"locale_it",
"locale_nl",
"locale_pl",
"locale_pt",
"locale_tr",
"locale_uk",
"locale_bg",
"locale_en",
"locale_mx",
"locale_ro",
"locale_ru",
"locale_dk",
"locale_cz",
"locale_hu",
"locale_us",
"locale_pa",
"locale",
"uiscript",
"ETC",
"uiloading",
@@ -257,7 +171,6 @@ bool PackInitialize(const char * c_pszFolder)
CPackManager::instance().AddPack(std::format("{}/{}.pck", c_pszFolder, packFileName));
}
NANOEND
return true;
}
@@ -270,7 +183,7 @@ bool RunMainScript(CPythonLauncher& pyLauncher, const char* lpCmdLine)
initgrpImage();
initgrpText();
initwndMgr();
/////////////////////////////////////////////
initudp();
initapp();
initsystem();
@@ -298,113 +211,36 @@ bool RunMainScript(CPythonLauncher& pyLauncher, const char* lpCmdLine)
initsafebox();
initguild();
initServerStateChecker();
std::string stRegisterDebugFlag;
NANOBEGIN
#ifdef _DISTRIBUTE
stRegisterDebugFlag = "__DEBUG__ = 0";
#else
stRegisterDebugFlag = "__DEBUG__ = 1";
#endif
// RegisterDebugFlag
if (!pyLauncher.RunLine(stRegisterDebugFlag.c_str()))
{
std::string stRegisterDebugFlag;
#ifdef _DISTRIBUTE
stRegisterDebugFlag ="__DEBUG__ = 0";
#else
stRegisterDebugFlag ="__DEBUG__ = 1";
#endif
if (!pyLauncher.RunLine(stRegisterDebugFlag.c_str()))
{
TraceError("RegisterDebugFlag Error");
return false;
}
TraceError("RegisterDebugFlag Error");
return false;
}
// RegisterCommandLine
if (!pyLauncher.RunFile("system.py"))
{
std::string stRegisterCmdLine;
const char * loginMark = "-cs";
const char * loginMark_NonEncode = "-ncs";
const char * seperator = " ";
std::string stCmdLine;
const int CmdSize = 3;
std::vector<std::string> stVec;
SplitLine(lpCmdLine,seperator,&stVec);
if (CmdSize == stVec.size() && stVec[0]==loginMark)
{
char buf[MAX_PATH]; //TODO 아래 함수 string 형태로 수정
base64_decode(stVec[2].c_str(),buf);
stVec[2] = buf;
string_join(seperator,stVec,&stCmdLine);
}
else if (CmdSize <= stVec.size() && stVec[0]==loginMark_NonEncode)
{
stVec[0] = loginMark;
string_join(" ",stVec,&stCmdLine);
}
else
stCmdLine = lpCmdLine;
stRegisterCmdLine ="__COMMAND_LINE__ = ";
stRegisterCmdLine+='"';
stRegisterCmdLine+=stCmdLine;
stRegisterCmdLine+='"';
const CHAR* c_szRegisterCmdLine=stRegisterCmdLine.c_str();
if (!pyLauncher.RunLine(c_szRegisterCmdLine))
{
TraceError("RegisterCommandLine Error");
return false;
}
}
{
std::vector<std::string> stVec;
SplitLine(lpCmdLine," " ,&stVec);
if (stVec.size() != 0 && "--pause-before-create-window" == stVec[0])
{
system("pause");
}
if (!pyLauncher.RunFile("system.py"))
{
TraceError("RunMain Error");
return false;
}
TraceError("RunMain Error");
return false;
}
NANOEND
return true;
}
bool Main(HINSTANCE hInstance, LPSTR lpCmdLine)
static bool Main(HINSTANCE hInstance, LPSTR lpCmdLine)
{
#ifdef LOCALE_SERVICE_YMIR
extern bool g_isScreenShotKey;
g_isScreenShotKey = true;
#endif
DWORD dwRandSeed=time(NULL)+DWORD(GetCurrentProcess());
DWORD dwRandSeed = (DWORD)time(NULL) ^ GetCurrentProcessId() ^ GetTickCount();
srandom(dwRandSeed);
srand(random());
SetLogLevel(1);
#ifdef LOCALE_SERVICE_VIETNAM_MILD
extern BOOL USE_VIETNAM_CONVERT_WEAPON_VNUM;
USE_VIETNAM_CONVERT_WEAPON_VNUM = true;
#endif
if (_access("perf_game_update.txt", 0)==0)
{
DeleteFile("perf_game_update.txt");
}
if (_access("newpatch.exe", 0)==0)
{
system("patchupdater.exe");
return false;
}
if (!Setup(lpCmdLine))
return false;
@@ -415,8 +251,8 @@ bool Main(HINSTANCE hInstance, LPSTR lpCmdLine)
OpenLogFile(false); // false == uses syserr.txt only
#endif
static CLZO lzo;
CPackManager packMgr;
static CLZO lzo;
CPackManager packMgr;
if (!PackInitialize("pack"))
{
@@ -424,57 +260,22 @@ bool Main(HINSTANCE hInstance, LPSTR lpCmdLine)
return false;
}
if(LocaleService_LoadGlobal(hInstance))
SetDefaultCodePage(LocaleService_GetCodePage());
auto app = new CPythonApplication;
app->Initialize (hInstance);
CPythonLauncher pyLauncher;
CPythonApplication * app = new CPythonApplication;
app->Initialize(hInstance);
bool ret=false;
if (pyLauncher.Create())
{
CPythonLauncher pyLauncher;
CPythonExceptionSender pyExceptionSender;
SetExceptionSender(&pyExceptionSender);
if (pyLauncher.Create())
{
ret=RunMainScript(pyLauncher, lpCmdLine); //게임 실행중엔 함수가 끝나지 않는다.
}
//ProcessScanner_ReleaseQuitEvent();
//게임 종료시.
app->Clear();
timeEndPeriod(1);
pyLauncher.Clear();
RunMainScript (pyLauncher, lpCmdLine);
}
app->Clear();
timeEndPeriod (1);
pyLauncher.Clear();
app->Destroy();
delete app;
return ret;
}
HANDLE CreateMetin2GameMutex()
{
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
return CreateMutex(&sa, FALSE, "Metin2GameMutex");
}
void DestroyMetin2GameMutex(HANDLE hMutex)
{
if (hMutex)
{
ReleaseMutex(hMutex);
hMutex = NULL;
}
return 0;
}
void __ErrorPythonLibraryIsNotExist()
@@ -482,100 +283,12 @@ void __ErrorPythonLibraryIsNotExist()
LogBoxf("FATAL ERROR!! Python Library file not exist!");
}
bool __IsTimeStampOption(LPSTR lpCmdLine)
{
const char* TIMESTAMP = "/timestamp";
return (strncmp(lpCmdLine, TIMESTAMP, strlen(TIMESTAMP))==0);
}
void __PrintTimeStamp()
{
#ifdef _DEBUG
if (__IS_TEST_SERVER_MODE__)
LogBoxf("METIN2 BINARY TEST DEBUG VERSION %s ( MS C++ %d Compiled )", __TIMESTAMP__, _MSC_VER);
else
LogBoxf("METIN2 BINARY DEBUG VERSION %s ( MS C++ %d Compiled )", __TIMESTAMP__, _MSC_VER);
#else
if (__IS_TEST_SERVER_MODE__)
LogBoxf("METIN2 BINARY TEST VERSION %s ( MS C++ %d Compiled )", __TIMESTAMP__, _MSC_VER);
else
LogBoxf("METIN2 BINARY DISTRIBUTE VERSION %s ( MS C++ %d Compiled )", __TIMESTAMP__, _MSC_VER);
#endif
}
bool __IsLocaleOption(LPSTR lpCmdLine)
{
return (strcmp(lpCmdLine, "--locale") == 0);
}
bool __IsLocaleVersion(LPSTR lpCmdLine)
{
return (strcmp(lpCmdLine, "--perforce-revision") == 0);
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
#ifdef _DEBUG
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF );
//_CrtSetBreakAlloc( 110247 );
#endif
LoadConfig("config/locale.cfg");
ApplicationStringTable_Initialize(hInstance);
LocaleService_LoadConfig("config/locale.cfg");
SetDefaultCodePage(LocaleService_GetCodePage());
bool bQuit = false;
int nArgc = 0;
PCHAR* szArgv = CommandLineToArgv( lpCmdLine, &nArgc );
for( int i=0; i < nArgc; i++ ) {
if(szArgv[i] == 0)
continue;
if (__IsLocaleVersion(szArgv[i])) // #0000829: [M2EU] 버전 파일이 항상 생기지 않도록 수정
{
char szModuleName[MAX_PATH];
char szVersionPath[MAX_PATH];
GetModuleFileName(NULL, szModuleName, sizeof(szModuleName));
sprintf(szVersionPath, "%s.version", szModuleName);
FILE* fp = fopen(szVersionPath, "wt");
if (fp)
{
extern int METIN2_GET_VERSION();
fprintf(fp, "r%d\n", METIN2_GET_VERSION());
fclose(fp);
}
bQuit = true;
} else if (__IsLocaleOption(szArgv[i]))
{
FILE* fp=fopen("locale.txt", "wt");
fprintf(fp, "service[%s] code_page[%d]",
LocaleService_GetName(), LocaleService_GetCodePage());
fclose(fp);
bQuit = true;
} else if (__IsTimeStampOption(szArgv[i]))
{
__PrintTimeStamp();
bQuit = true;
} else if ((strcmp(szArgv[i], "--force-set-locale") == 0))
{
// locale 설정엔 인자가 두 개 더 필요함 (로케일 명칭, 데이터 경로)
if (nArgc <= i + 2)
{
MessageBox(NULL, "Invalid arguments", ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP);
goto Clean;
}
const char* localeName = szArgv[++i];
const char* localePath = szArgv[++i];
LocaleService_ForceSetLocale(localeName, localePath);
}
}
if(bQuit)
goto Clean;
auto szArgv = CommandLineToArgv (lpCmdLine, &nArgc);
if (!CheckPythonLibraryFilenames())
{
@@ -583,36 +296,23 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
goto Clean;
}
Main(hInstance, lpCmdLine);
Main (hInstance, lpCmdLine);
::CoUninitialize();
if(gs_szErrorString[0])
MessageBox(NULL, gs_szErrorString, ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP);
Clean:
SAFE_FREE_GLOBAL(szArgv);
SAFE_FREE_GLOBAL (szArgv);
return 0;
}
static void GrannyError(granny_log_message_type Type,
granny_log_message_origin Origin,
char const* File,
granny_int32x Line,
char const* Message,
void* UserData)
static void GrannyError(granny_log_message_type Type, granny_log_message_origin Origin, char const* File, granny_int32x Line, char const* Message, void* UserData)
{
TraceError("GRANNY: %s", Message);
TraceError("GRANNY: %s", Message);
}
int Setup(LPSTR lpCmdLine)
{
/*
* 타이머 정밀도를 올린다.
*/
TIMECAPS tc;
UINT wTimerRes;
TIMECAPS tc;
UINT wTimerRes;
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR)
return 0;
@@ -620,13 +320,9 @@ int Setup(LPSTR lpCmdLine)
wTimerRes = MINMAX(tc.wPeriodMin, 1, tc.wPeriodMax);
timeBeginPeriod(wTimerRes);
/*
* 그래니 에러 핸들링
*/
granny_log_callback Callback;
Callback.Function = nullptr;
Callback.UserData = 0;
GrannySetLogCallback(&Callback);
Callback.Function = nullptr;
Callback.UserData = 0;
GrannySetLogCallback(&Callback);
return 1;
}

View File

@@ -1,7 +1,7 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include "version.h"
#include "version.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
@@ -15,60 +15,12 @@
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// 일본어 resources
// English (United States) resources
//
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
#ifdef _WIN32
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
#pragma code_page(932)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_POSSESSIVE_MORPHENE "'s"
END
#endif // 일본어 resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// 중국어(중국) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_POSSESSIVE_MORPHENE "'s"
IDS_WARN_BAD_DRIVER "句寡퀭콘뫘劤鞫엥혜땡。"
IDS_WARN_NO_TNL "퀭돨鞫엥꼇連넣3D TnL 袒숭속醵\n踏狗쉥轟랬攣끽頓契。"
END
#endif // 중국어(중국) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// 한국어 resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR)
#ifdef _WIN32
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
#pragma code_page(949)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(65001)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
@@ -79,7 +31,7 @@ LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
IDD_SELECT_LOCALE DIALOGEX 0, 0, 182, 142
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
CAPTION "SELECT LOCALE"
FONT 10, "Arial", 0, 0, 0x0
FONT 10, "Tahoma", 0, 0, 0x0
BEGIN
PUSHBUTTON "START",IDC_START,44,123,40,13
PUSHBUTTON "EXIT",IDC_EXIT,96,123,40,13
@@ -93,18 +45,18 @@ END
// TEXTINCLUDE
//
1 TEXTINCLUDE
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"#include \"afxres.h\"\r\n"
"\0"
END
3 TEXTINCLUDE
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
@@ -118,19 +70,19 @@ END
// Cursor
//
IDC_CURSOR_NORMAL CURSOR "Cursors\\cursor.cur"
IDC_CURSOR_CHAIR CURSOR "Cursors\\cursor_chair.cur"
IDC_CURSOR_DOOR CURSOR "Cursors\\cursor_door.cur"
IDC_CURSOR_NO CURSOR "Cursors\\cursor_no.cur"
IDC_CURSOR_PICK CURSOR "Cursors\\cursor_pick.cur"
IDC_CURSOR_TALK CURSOR "Cursors\\cursor_talk.cur"
IDC_CURSOR_ATTACK CURSOR "Cursors\\cursor_attack.cur"
IDC_CURSOR_BUY CURSOR "cursors\\cursor_buy.cur"
IDC_CURSOR_SELL CURSOR "cursors\\cursor_sell.cur"
IDC_CURSOR_NORMAL CURSOR "Cursors\\cursor.cur"
IDC_CURSOR_CHAIR CURSOR "Cursors\\cursor_chair.cur"
IDC_CURSOR_DOOR CURSOR "Cursors\\cursor_door.cur"
IDC_CURSOR_NO CURSOR "Cursors\\cursor_no.cur"
IDC_CURSOR_PICK CURSOR "Cursors\\cursor_pick.cur"
IDC_CURSOR_TALK CURSOR "Cursors\\cursor_talk.cur"
IDC_CURSOR_ATTACK CURSOR "Cursors\\cursor_attack.cur"
IDC_CURSOR_BUY CURSOR "Cursors\\cursor_buy.cur"
IDC_CURSOR_SELL CURSOR "Cursors\\cursor_sell.cur"
IDC_CURSOR_CAMERA_ROTATE CURSOR "Cursors\\cursor_camera_rotate.cur"
IDC_CURSOR_HSIZE CURSOR "Cursors\\cursor_hsize.cur"
IDC_CURSOR_VSIZE CURSOR "Cursors\\cursor_vsize.cur"
IDC_CURSOR_HVSIZE CURSOR "Cursors\\cursor_hvsize.cur"
IDC_CURSOR_HSIZE CURSOR "Cursors\\cursor_hsize.cur"
IDC_CURSOR_VSIZE CURSOR "Cursors\\cursor_vsize.cur"
IDC_CURSOR_HVSIZE CURSOR "Cursors\\cursor_hvsize.cur"
/////////////////////////////////////////////////////////////////////////////
//
@@ -138,7 +90,7 @@ IDC_CURSOR_HVSIZE CURSOR "Cursors\\cursor_hvsize.cur"
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
GUIDELINES DESIGNINFO
BEGIN
IDD_SELECT_LOCALE, DIALOG
BEGIN
@@ -164,7 +116,7 @@ IDI_METIN2 ICON "metin2.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILE_VERSION
FILEVERSION VER_FILE_VERSION
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
@@ -178,7 +130,8 @@ VS_VERSION_INFO VERSIONINFO
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080003b5"
// 0409 = en-US, 04B0 = Unicode
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "Ymir Entertainment"
VALUE "FileDescription", "Metin2Client"
@@ -192,67 +145,31 @@ BEGIN
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x800, 949
VALUE "Translation", 0x0409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
STRINGTABLE
BEGIN
IDS_APP_NAME "메틴2"
IDS_POSSESSIVE_MORPHENE "의"
IDS_WARN_BAD_DRIVER "그래픽 드라이버를 업데이트 하시기 바랍니다."
IDS_WARN_NO_TNL "사용하고 계신 시스템의 그래픽카드는 3D TnL 하드웨어 가속이 지원되지 않아\n게임이 느리게 실행되거나 제대로 실행되지 않을수 있습니다."
IDS_ERR_CANNOT_READ_FILE "%s 파일을 읽을 수 없습니다."
IDS_ERR_NOT_LATEST_FILE "'%s' 파일은 최신버전이 아닙니다. 런처를 다시 실행해주세요."
IDS_ERR_MUST_LAUNCH_FROM_PATCHER "클라이언트는 패처를 사용해서 실행되어야 합니다."
IDS_APP_NAME "Metin 2"
IDS_POSSESSIVE_MORPHENE "'s"
IDS_WARN_BAD_DRIVER "Please update your graphics driver."
IDS_WARN_NO_TNL "Your graphics card does not support 3D TnL hardware acceleration. The game may not run properly."
IDS_ERR_CANNOT_READ_FILE "Cannot read %s file"
IDS_ERR_NOT_LATEST_FILE "File '%s' is not the latest version. Please launch the patcher."
IDS_ERR_MUST_LAUNCH_FROM_PATCHER "Please run the patcher."
END
#endif // 한국어 resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// 영어(미국) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_APP_NAME "Metin 2"
IDS_POSSESSIVE_MORPHENE "'s"
IDS_WARN_BAD_DRIVER "IDS_WARN_BAD_DRIVER"
IDS_WARN_NO_TNL "IDS_WARN_NO_TNL"
IDS_ERR_CANNOT_READ_FILE "Cannot read %s file"
IDS_ERR_NOT_LATEST_FILE "File '%s' is not latest version. Please launch patcher."
IDS_ERR_MUST_LAUNCH_FROM_PATCHER "Please run patcher."
END
#endif // 영어(미국) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED