Restructure repository to include all source folders

Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
#include "stdafx.h"
#include <Log/ServerLog.h>
#include <Utility/Math/Math.h>
#include <Character/ModifyCharacter.h>
bool CSkillID::ReadSkillScript(char* szScriptName)
{
const int MAX_LINE = 4096;
const char SKILL_ID_LEN = 32;
const char SKILL_TYPE_LEN = 32;
char cLineBuffer[MAX_LINE];
char cSkillID[SKILL_ID_LEN];
char cSkillType[SKILL_TYPE_LEN];
unsigned short BeforeID = 0, AfterID = 1;
FILE* lpStream = fopen(szScriptName, "rt");
if(NULL == lpStream)
{
ERRLOG1(g_Log, "스킬 스크립트 파일 열기 실패. 파일명: %s", szScriptName);
return false;
}
fgets(cLineBuffer, MAX_LINE, lpStream); // 첫 라인 제거 (컬럼명)
while(!feof(lpStream))
{
fgets(cLineBuffer, MAX_LINE, lpStream);
sscanf(cLineBuffer, "%s %s", cSkillID, cSkillType);
if(stricmp(cSkillType, "ITEM")) // 스킬타입이 아이템이 아닐 경우만
{
if((*cSkillID == '0') && (*(cSkillID + 1) == 'x')) // 0x로 시작하는지 체크
{
AfterID = Math::Convert::Atos(cSkillID);
if(AfterID != BeforeID)
{
insert(AfterID);
BeforeID = AfterID;
}
}
}
*cLineBuffer = *cSkillID = 0;
}
fclose(lpStream);
return true;
}

View File

@@ -0,0 +1,228 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="AdminToolLibrary"
ProjectGUID="{80EDF2CA-C3CA-4240-861B-ECD05A89CA3D}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../Executable/$(ConfigurationName)"
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
UseOfMFC="0"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../../RylServerProject;../../RylServerProject/BaseLibrary;../../RylServerProject/RylServerLibrary;../../RylServerProject/RylGameLibrary;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/RylToolLibrary.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../Executable/$(ConfigurationName)"
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
UseOfMFC="0"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="./;../../RylServerProject;../../RylServerProject/BaseLibrary;../../RylServerProject/RylServerLibrary;../../RylServerProject/RylGameLibrary;"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/RylToolLibrary.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="DBComponent"
Filter="">
<File
RelativePath=".\dbcomponent\AuthDB.cpp">
</File>
<File
RelativePath=".\dbcomponent\AuthDB.h">
</File>
<File
RelativePath=".\dbcomponent\BillingDB.cpp">
</File>
<File
RelativePath=".\dbcomponent\BillingDB.h">
</File>
<File
RelativePath=".\DBComponent\Ryl_AdminMgrDB.cpp">
</File>
<File
RelativePath=".\DBComponent\Ryl_AdminMgrDB.h">
</File>
<File
RelativePath=".\dbcomponent\Ryl_DetailLog.cpp">
</File>
<File
RelativePath=".\dbcomponent\Ryl_DetailLog.h">
</File>
<File
RelativePath=".\DBComponent\RYL_GameDB.cpp">
</File>
<File
RelativePath=".\DBComponent\RYL_GameDB.h">
</File>
</Filter>
<Filter
Name="Network"
Filter="">
<Filter
Name="Protocol"
Filter="">
<File
RelativePath=".\Network\Protocol\RYL_AdminMgrProtocol.h">
</File>
</Filter>
<Filter
Name="AgentServerParseData"
Filter="">
<File
RelativePath=".\Network\AgentServerParseData\Ryl_AgentServerParseData.h">
</File>
<File
RelativePath=".\Network\AgentServerParseData\Ryl_ParseGetData.cpp">
</File>
<File
RelativePath=".\Network\AgentServerParseData\Ryl_ParseSetData.cpp">
</File>
</Filter>
<Filter
Name="Buffer"
Filter="">
<File
RelativePath=".\Network\Buffer\RYL_CumulateBuffer.cpp">
</File>
<File
RelativePath=".\Network\Buffer\RYL_CumulateBuffer.h">
</File>
</Filter>
</Filter>
<Filter
Name="Character"
Filter="">
<File
RelativePath=".\LearnSkill.cpp">
</File>
<File
RelativePath=".\Character\ModifyCharacter.cpp">
</File>
<File
RelativePath=".\Character\ModifyCharacter.h">
</File>
<File
RelativePath=".\Ryl_ItemData.cpp">
</File>
<File
RelativePath=".\Ryl_ModifyCharacterMgr.cpp">
</File>
</Filter>
<Filter
Name="Parser"
Filter="">
<File
RelativePath=".\Parser\ServerInfo.cpp">
</File>
<File
RelativePath=".\Parser\ServerInfo.h">
</File>
</Filter>
<Filter
Name="Script"
Filter="">
<File
RelativePath=".\ToolQuestList.cpp">
</File>
<File
RelativePath=".\ToolQuestList.h">
</File>
</Filter>
<File
RelativePath=".\stdafx.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
<File
RelativePath=".\stdafx.h">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,165 @@
#include "stdafx.h"
#include <Character/ModifyCharacter.h>
#include <Item/ItemFactory.h>
#include <Log/ServerLog.h>
namespace ItemData
{
// 아이템 좌표를 만든다.
Item::ItemPos MakeItemPos(unsigned char cPos, unsigned char cX, unsigned char cY, unsigned char cZ)
{
Item::ItemPos itemPos;
itemPos.m_cPos = cPos;
if(IsArrayContainer(cPos))
{
itemPos.SetPos(cX, cY, cZ);
}
else
{
itemPos.m_cIndex = cX;
}
return itemPos;
}
// 아이템위치가 적정한위치인지 확인..
inline bool IsArrayContainer(unsigned char cTakePos)
{
switch(cTakePos)
{
case TakeType::TS_INVEN:
case TakeType::TS_EXCHANGE:
case TakeType::TS_DEPOSIT:
case TakeType::TS_STALL:
return true;
}
return false;
}
// 아이템 복사..
Item::CItem* CloneItem(Item::CItem* lpSrcItem, PktAdminMgr::CreateItemInfo EquipInfo)
{
if (0 != lpSrcItem)
{
Item::CEquipment* lpEquipment = Item::CEquipment::DowncastToEquipment(lpSrcItem);
if (0 != lpEquipment)
{
Item::CItem* lpNewItem =
Item::CItemFactory::GetInstance().CreateItem(lpEquipment->GetItemInfo());
Item::CEquipment* lpNewEquipment =
Item::CEquipment::DowncastToEquipment(lpNewItem);
if(0 == lpNewEquipment)
{
DELETE_ITEM(lpNewItem);
}
else
{
lpNewEquipment->SetNumOrDurability(lpSrcItem->GetNumOrDurability());
static_cast<CModifyEquipment*>(lpNewEquipment)->AdjustData(EquipInfo);
DETLOG0(g_Log, "Item::CEquipment* 복사 아이템을 생성했습니다.");
return lpNewEquipment;
}
}
else
{
Item::CItem* lpItem =
new Item::CItem(lpSrcItem->GetItemInfo());
if (0 != lpItem)
{
lpItem->SetNumOrDurability(lpSrcItem->GetNumOrDurability());
DETLOG0(g_Log, "Item::CItem* 복사 아이템을 생성했습니다.");
return lpItem;
}
}
}
else
{
ERRLOG0(g_Log, "원본 아이템이 NULL입니다");
}
return NULL;
}
// 리턴값 :
// 내가 사용할수 있으면 true 사용할수 없으면 false
// 리턴값이 false && bisLock가 false면 내가 창고에 락을 걸고 사용하면된다.
bool CDepositLock::isUse( unsigned long dwUID, unsigned long dwCID, CPacketDispatch* lpPacketDispatch, bool& bisLock )
{
isDepositPos Pos = m_DepositUser.find( dwUID );
if( Pos != end( ) )
{
bisLock = true;
DepositInfo& Info = Pos->second;
if( ( dwCID == Info.m_dwCID ) && ( Info.m_lpPacketDispatch == lpPacketDispatch ) )
{
return true;
}
}
else
{
bisLock = false;
}
return false;
}
// 창고 잠금정보를 저장한다
void CDepositLock::DepositLock( unsigned long dwUID, unsigned long dwCID, CPacketDispatch* lpPacketDispatch )
{
m_DepositUser.insert( std::make_pair( dwUID, DepositInfo( dwCID, lpPacketDispatch ) ) );
}
// 창고 잠금정보를 해지..
void CDepositLock::DepositUnLock( unsigned long dwUID )
{
isDepositPos Pos = m_DepositUser.find( dwUID );
if( Pos != end( ) ) m_DepositUser.erase( Pos );
}
// 창고를 독점하고있는 관리자의 Dispatch를 가져온다.
CPacketDispatch* CDepositLock::GetDispatch( unsigned long dwUID )
{
isDepositPos Pos = m_DepositUser.find( dwUID );
if( Pos != end( ) )
{
DepositInfo& Info = Pos->second;
return Info.m_lpPacketDispatch;
}
return NULL;
}
// 창고 잠금 정보를 가져온다.
bool CDepositLock::GetLockInfo( unsigned long dwUID, CDepositLock::DepositInfo& Info )
{
isDepositPos Pos = m_DepositUser.find( dwUID );
if( Pos != end( ) )
{
Info = Pos->second;
return true;
}
return false;
}
// 해당 Dispatch를 가지고 있는 창고 장금정보를 모두 해지한다.
void CDepositLock::RemoveAllSelectDispatch( CPacketDispatch* lpPacketDispatch )
{
isDepositPos Pos = m_DepositUser.begin( );
for(;Pos != end( );)
{
DepositInfo& Info = Pos->second;
if( Info.m_lpPacketDispatch == lpPacketDispatch )
{
m_DepositUser.erase( Pos++ );
}
else
{
++Pos;
}
}
}
};

View File

@@ -0,0 +1,85 @@
#include "stdafx.h"
#include < Network/Session/Session.h>
#include < Network/Dispatch/Dispatch.h >
#include < Character/ModifyCharacter.h >
// CModifyCharacterMgr ----------------------------------------------------------
// 해당 UID를 편집중인 관리자들에게 해당 패킷을 보낸다
void CModifyCharacterMgr::isUIDSendAll(unsigned long dwUID, CBuffer* lpBuffer)
{
iterator pos = begin();
for(;pos != end(); ++pos)
{
CModifyCharacter* Character = pos->second;
if(dwUID == Character->GetUID())
{
CPacketDispatch* lpPacketDispatch = Character->GetDispatch();
if(NULL != lpPacketDispatch)
{
CSession& lpSession = lpPacketDispatch->GetSession();
lpSession.Send( /*lpBuffer*/ );
}
}
}
}
// 편집 하고자하는 캐릭터를 등록한다.
CModifyCharacter* CModifyCharacterMgr::InsertChar(unsigned long dwCID)
{
CModifyCharacter* lpModifyCharacter = CreateCharacter();
m_mapModifyChar.insert(std::make_pair(dwCID, lpModifyCharacter));
return lpModifyCharacter;
}
// 편집이 끝났거나 해당 Session이 닫히면 캐릭터를 지워주자.
bool CModifyCharacterMgr::EraseChar(unsigned long dwCID)
{
isMapCharList::iterator itr = m_mapModifyChar.find(dwCID);
if(itr != m_mapModifyChar.end())
{
delete itr->second;
m_mapModifyChar.erase(itr);
return true;
}
return false;
}
// 리스트에 등록되어있는 캐릭터데이터를 찾는다
CModifyCharacter* CModifyCharacterMgr::GetCharacter(unsigned long dwCID)
{
isMapCharList::iterator itr = m_mapModifyChar.find(dwCID);
if(itr != m_mapModifyChar.end())
return itr->second;
return NULL;
}
// 현재 Dispatch를 사용하는 캐릭터를 찾아 전부 리스트에서 삭제
void CModifyCharacterMgr::AllRemoveChar(CPacketDispatch* lpPacketDispatch)
{
isMapCharList::iterator itr = m_mapModifyChar.begin();
for(; itr != m_mapModifyChar.end();)
{
CPacketDispatch* lpDispatch = itr->second->GetDispatch();
if(lpDispatch == lpPacketDispatch)
{
delete itr->second;
m_mapModifyChar.erase(itr++);
}
else
{
++itr;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,220 @@
#ifndef __TOOL_QUEST_LIST_H__
#define __TOOL_QUEST_LIST_H__
#include <windows.h>
#include <vector>
#include <map>
#define TRIGGER_START 0
#define TRIGGER_PUTON 1
#define TRIGGER_GETON 2
#define TRIGGER_TALK 3
#define TRIGGER_KILL 4
#define TRIGGER_PICK 5
#define TRIGGER_FAME 6
#define TRIGGER_LEVEL_TALK 7
#define TRIGGER_FAME_TALK 8
#define TRIGGER_ABILITY_TALK 9
#define EVENT_DISAPPEAR 0
#define EVENT_GET 1
#define EVENT_SPAWN 2
#define EVENT_MONSTERDROP 3
#define EVENT_END 4
#define EVENT_AWARD 5
#define EVENT_MSGBOX 6
#define EVENT_PHASE 7
#define EVENT_ADDQUEST 8
#define EVENT_AWARDITEM 9
#define EVENT_AWARDITEMID 10 // 이벤트 : 장비 보상
#define EVENT_AWARDITEMCLASS 11 // 이벤트 : 장비 보상
#define EVENT_MOVE 12 // 이벤트 : 존 이동
#define EVENT_THEATERMODE 13 // 이벤트 : 씨어터 모드
#define EVENT_ALARMBOX 14 // 이벤트 : 알람 메세지 박스 출력
#define NPC_QUEST 0 // NPC 가 주는 퀘스트
#define ITEM_QUEST 1 // 아이템 사용을 통한 퀘스트
#define AREA_QUEST 2 // 위치 트리거 퀘스트
#define PARTY_QUEST_BIT 0xF000 // 파티 퀘스트 비트
using namespace std;
typedef struct EventNode
{
unsigned long m_dwEventKind;
unsigned long m_dwEventNumber;
unsigned long m_dwEventAmount;
unsigned long m_dwEventAmount2;
unsigned long m_dwEventAmount3;
float m_fPosX;
float m_fPosY;
float m_fPosZ;
char *m_strWord;
} EventNode, *LPEventNode;
typedef struct TriggerNode
{
unsigned long m_dwTriggerKind;
unsigned long m_dwTriggerID;
unsigned long m_dwZoneID;
unsigned long m_dwMaxCount;
unsigned long m_dwLevel;
float m_fPosX;
float m_fPosY;
float m_fPosZ;
float m_fDistance;
std::string m_strElseMsg; // LevelTalk 에서 Level이 맞지 않을때 출력될 메세지
vector<LPEventNode> m_lstEvent;
vector<LPEventNode> m_lstFalseEvent;
vector<char *> m_lstMsgBox;
vector<char *> m_lstFalseMsgBox;
} TriggerNode, *LPTriggerNode;
typedef struct TargetPos
{
int m_iType;
unsigned long m_dwPosX;
unsigned long m_dwPosY;
} TargetPos;
typedef struct PhaseNode
{
unsigned long m_dwZoneID;
unsigned long m_dwPhaseNumber;
char *m_strPhaseDesc;
vector<LPTriggerNode> m_lstTrigger;
vector<TargetPos> m_lstTargetPos;
LPTriggerNode GetTrigger(unsigned long dwTriggerKind, unsigned long dwStartPos, unsigned long *dwTriggerPos)
{
vector<LPTriggerNode>::iterator it;
*dwTriggerPos = 0;
dwStartPos++;
for(it = m_lstTrigger.begin(); it != m_lstTrigger.end(); it++, *dwTriggerPos++)
{
if(dwStartPos <= *dwTriggerPos)
{
if((*it)->m_dwTriggerKind == dwTriggerKind) return (*it);
}
}
return NULL;
}
} PhaseNode, *LPPhaseNode;
typedef struct QuestNode
{
enum eCheckResult
{
RES_SUCCESS = 0, // 성공
RES_MISMATCH_CLASS = 1, // 클래스가 맞지 않음
RES_ALREADY_TAKEN = 2, // 이미 받은 퀘스트
RES_NOT_COMPLETE_PRIOR_QUEST = 3, // 선결 퀘스트를 완료하지 않았음
RES_HIGH_THAN_MAX_LEVEL = 4, // 수행할 수 있는 최고 레벨보다 높다.
RES_10_LOW_THAN_MIN_LEVEL = 5, // 수행할 수 있는 최저 레벨보다 10 레벨 낮다.
RES_LOW_LEVEL = 6, // 수행할 수 있는 레벨보다 조금 낮다.
RES_MISMATCH_NATION = 7, // 수행할 수 없는 국적입니다.
RES_LOW_FAME = 8, // 수행할 수 있는 명성보다 조금 낮다.
RES_HIGH_THAN_MAX_FAME = 9, // 수행할 수 있는 최고 명성 보다 높다.
};
enum eCheckNation
{
NATION_ALL = 0, // 모든 국가( 카르테란트 + 메르카디아 + 신의해적단 )
NATION_KARTERANT = 1, // 카르테란트
NATION_MERKADIA = 2, // 메르카디아
NATION_ALMIGHTY_PIRATE = 3, // 신의해적단
// 사용 예
// 12 : 카르테란트 + 메르카디아
// 13 : 카르테란트 + 신의해적단
// 23 : 메르카디아 + 신의해적단
// 123 : 카르테란트 + 메르카디아 + 신의해적단 = 0 (모든 국가)
};
unsigned short m_wQuestID;
unsigned short m_wQuestType;
unsigned short m_wMaxPhase;
unsigned short m_wMinLevel;
unsigned short m_wMaxLevel;
unsigned long m_dwMinFame;
unsigned long m_dwMaxFame;
unsigned long m_dwClass;
unsigned short m_usNation; // 퀘스트 수행 가능 국가
BOOL m_bNationDependent; // 퀘스트가 국가 종속성이라서 국적이 바뀌면 지워지는가?
unsigned short m_usBonusSkillPoint; // 퀘스트 수행 후 받는 보너스 스킬 포인트
unsigned short m_usBonusAbilityPoint; // 퀘스트 수행 후 받는 보너스 스킬 포인트
unsigned long m_dwCompletedQuest;
char *m_strQuestTitle;
char *m_strQuestDesc;
char *m_strQuestShortDesc;
char *m_strQuestLevel;
char *m_strQuestAward;
char m_strIconTexture[32];
unsigned short m_wPosX1, m_wPosY1;
unsigned short m_wPosX2, m_wPosY2;
BOOL m_bSave;
BOOL m_bInvisible; // pop up 메뉴에서 안보이는지 여부
float m_fPosX; // 위치 퀘스트의 영역 중심 위치
float m_fPosY;
float m_fPosZ;
float m_fDistance; // 중심 위치에서의 거리
unsigned long m_dwZoneID; // 위치 퀘스트를 받는 존
vector<LPPhaseNode> m_lstPhase;
LPPhaseNode GetPhase(unsigned long dwPhase)
{
vector<LPPhaseNode>::iterator it;
for(it = m_lstPhase.begin(); it != m_lstPhase.end(); it++)
{
if((*it)->m_dwPhaseNumber == dwPhase) return (*it);
}
return NULL;
}
unsigned short GetQuestType() { return (m_wQuestType & ~PARTY_QUEST_BIT); }
bool IsPartyQuest() { return (0 != (m_wQuestType & PARTY_QUEST_BIT)); }
unsigned long CheckQuest(unsigned long dwLevel, unsigned long dwFame, unsigned long dwClass, unsigned long dwNation, unsigned short *lstCompleted, unsigned short wNumCompleted, unsigned short *lstQuestList);
} QuestNode, *LPQuestNode;
typedef struct QuestInstanceNode
{
unsigned short m_wQuestID;
LPQuestNode m_lpQuest;
} QuestInstanceNode, *LPQuestInstanceNode;
class CQuestList
{
public:
LPQuestNode m_lpQuestNode;
LPPhaseNode m_lpPhaseNode;
LPTriggerNode m_lpTriggerNode;
vector<LPQuestNode> m_lstQuestNode;
CQuestList();
~CQuestList();
BOOL Load(const char *strQuestScriptFile);
LPQuestNode GetQuest(unsigned short wQuestID);
protected:
void DestroyQuestList();
};
extern CQuestList g_QuestList;
#endif // __TOOL_QUEST_LIST_H__

View File

@@ -0,0 +1,610 @@
#include "stdafx.h"
#include "ModifyCharacter.h"
#include <Network/Dispatch/Dispatch.h>
#include <Network/Protocol/Ryl_AdminMgrProtocol.h>
#include <Network/Packet/PacketStruct/CharStatusPacket.h>
#include <Network/Packet/PacketStruct/CharQuestPacket.h>
#include <Skill/SkillMgr.h>
#include <Item/ItemStructure.h>
#include <Log/ServerLog.h>
#include <Quest/QuestMgr.h>
#include <Creature/Character/CharacterClass.h>
#include <Creature/CreatureStructure.h>
CModifyCharacter::CModifyCharacter()
: CCharacter(0, 0)
, m_dwServerGroup(0)
, m_byChangedInfo(0)
, m_bScheduleClose(false)
, m_bSave(false)
, m_bIsOwnCopyItem(false)
{
Initialize(NULL);
ZeroMemory(&m_ExtraData, sizeof(CHAR_EXTRA_DATA));
m_ModifyCharItemSerialInfo.clear();
m_OverlapSerialInfo.clear();
m_cOldServerGroupID = UnifiedConst::Part2Selectable;
}
// 이녀석은 사용하지 말자 Initialize <- 이녀석 캐릭터 생성후 딱~~ 1번만 사용하자
// 그렇지 않으면 메모리 샌다 ㅡ.ㅡ;
void CModifyCharacter::Reset()
{
SetUID(0);
SetCID(0);
m_dwServerGroup = 0;
m_byChangedInfo = 0;
m_bScheduleClose = false;
ZeroMemory(&m_DBData, sizeof(CharacterDBData));
Initialize(NULL);
}
unsigned short CModifyCharacter::GetMaxSkillPoint()
{
// CalculateStatusData가 선행되어야 함.
return m_CreatureStatus.m_StatusInfo.m_wSkillPoint;
}
// 스킬 추가 및 스킬 레벨 변경 (이미 습득한 스킬을 추가 요청한다면 레벨 수정으로 인식)
unsigned char CModifyCharacter::AppendSkill(unsigned short wSkillID, char cLevel, char cLockCount)
{
m_DBData.m_Skill.wSkillNum = m_DBData.m_Skill.GetSkillNum(); // 현재 스킬수 재 계산
const Skill::ProtoType* lpSkillProtoType = CSkillMgr::GetInstance().GetSkillProtoType(wSkillID);
short sSlotIndex = GetSkillSlotIndex(wSkillID);
bool bIsNewSkill = false; // 새 스킬 습득 여부
if(-1 == sSlotIndex) bIsNewSkill = true;
if(NULL == lpSkillProtoType)
{
ERRLOG1(g_Log, "스킬 프로토 타입 얻기 실패. 스킬ID: 0x%04x", wSkillID);
return PktAdminMgr::PktSkillEdit::FAILED_TO_GET_SKILLPROTOTYPE;
}
if(CSkillMgr::MAX_SKILL_LOCKCOUNT <= cLockCount)
{
ERRLOG1(g_Log, "최대 스킬 락 카운트를 초과하였습니다. 락 카운트: %c", cLockCount);
return PktAdminMgr::PktSkillEdit::OVERED_MAX_LOCKCOUNT;
}
if(CSkillMgr::MAX_SKILL_LEVEL < cLevel)
{
ERRLOG1(g_Log, "최대 스킬 레벨을 초과하였습니다. 스킬 레벨: %c", cLevel);
return PktAdminMgr::PktSkillEdit::OVERED_MAX_SKILL_LEVEL;
}
if(lpSkillProtoType[0].m_usSkill_ID != lpSkillProtoType[cLockCount].m_usSkill_ID)
{
ERRLOG2(g_Log, "스킬 ID가 다릅니다. 0x%04x : 0x%04x", lpSkillProtoType[0].m_usSkill_ID,
lpSkillProtoType[cLockCount].m_usSkill_ID);
return PktAdminMgr::PktSkillEdit::FAILED;
}
// 최대 스킬 레벨을 추가할 경우 (다음 단계로 넘어가는 경우)
if(cLevel == CSkillMgr::MAX_SKILL_LEVEL)
{
// 최종 단계 스킬이 아닌경우 다음 단계 0레벨 스킬로 습득
if(cLockCount < CSkillMgr::MAX_SKILL_LOCKCOUNT - 1) // 아직 0~3 단계까지만 사용중
{
cLevel = 0;
++cLockCount;
}
}
// 새로운 스킬 습득
if(bIsNewSkill && (m_DBData.m_Skill.wSlotNum < SKILL::MAX_SLOT_NUM))
{
sSlotIndex = m_DBData.m_Skill.wSlotNum; // 새 슬롯 얻기
}
else if(m_DBData.m_Skill.wSlotNum == SKILL::MAX_SLOT_NUM)
{
ERRLOG0(g_Log, "이미 사용할 수 있는 최대 슬롯을 사용중입니다.");
return PktAdminMgr::PktSkillEdit::NOT_ENOUGH_SKILLSLOT;
}
SKILLSLOT TempSkillSlot;
TempSkillSlot.SKILLINFO.wSkill = wSkillID;
TempSkillSlot.SKILLINFO.cSkillLevel = cLevel;
TempSkillSlot.SKILLINFO.cLockCount = cLockCount;
unsigned short cResult = ReadSkill(TempSkillSlot, wSkillID, cLockCount);
if(PktBase::NO_SERVER_ERR == cResult) // 사용 가능한 스킬임
{
SKILL& Skill = m_DBData.m_Skill;
SKILLSLOT& SkillSlot = Skill.SSlot[sSlotIndex];
ChkEmptySlot(Skill); // 빈 슬롯을 가지고 있는지 체크
unsigned short BeforePoint =
(SkillSlot.SKILLINFO.cLockCount * CSkillMgr::MAX_SKILL_LOCKCOUNT) + SkillSlot.SKILLINFO.cSkillLevel;
unsigned short AfterPoint =
(cLockCount * CSkillMgr::MAX_SKILL_LOCKCOUNT) + cLevel;
// 기존 스킬 레벨 변경
if((!bIsNewSkill) && (GetMaxSkillPoint() >= ((GetSkillPoint() - BeforePoint) + AfterPoint)))
{
SkillSlot.SKILLINFO.wSkill = wSkillID;
SkillSlot.SKILLINFO.cSkillLevel = cLevel;
SkillSlot.SKILLINFO.cLockCount = cLockCount;
}
// 새로운 스킬 추가
else if(bIsNewSkill && (GetMaxSkillPoint() >= (GetSkillPoint() + AfterPoint)))
{
SkillSlot.SKILLINFO.wSkill = wSkillID;
SkillSlot.SKILLINFO.cSkillLevel = cLevel;
SkillSlot.SKILLINFO.cLockCount = cLockCount;
++m_DBData.m_Skill.wSlotNum; // 사용중인 슬롯수 + 1
}
UpdateQuickSlotSkill(SkillSlot);
m_DBData.m_Skill.wSkillNum = m_DBData.m_Skill.GetSkillNum();
}
else
{
switch(cResult)
{
case PktSk::FAIL_NOT_CURRENT_CLASS:
return PktAdminMgr::PktSkillEdit::NOT_CURRENT_CLASS;
case PktSk::FAIL_NOT_ENOUGH_STATUS:
return PktAdminMgr::PktSkillEdit::NOT_ENOUGH_STAT;
case PktSk::FAIL_MAX_LEVEL:
return PktAdminMgr::PktSkillEdit::OVERED_MAX_SKILL_LEVEL;
case PktSk::FAIL_NOT_CURRENT_LOCK_COUNT:
return PktAdminMgr::PktSkillEdit::FAILED;
default:
return PktAdminMgr::PktSkillEdit::FAILED;
}
}
return PktAdminMgr::PktSkillEdit::SUCCESS;
}
// 스킬 삭제 (스킬 포인트 조정 및 해당 스킬 슬롯 정보 초기화)
unsigned char CModifyCharacter::DeleteSkill(unsigned short wSkillID, char cLevel, char cLockCount)
{
m_DBData.m_Skill.wSkillNum = m_DBData.m_Skill.GetSkillNum(); // 현재 스킬수 재 계산
short sDelSlotIndex = GetSkillSlotIndex(wSkillID);
if(-1 != sDelSlotIndex)
{
SKILL& Skill = m_DBData.m_Skill;
SKILLSLOT& DelSlot = Skill.SSlot[sDelSlotIndex];
ChkEmptySlot(Skill); // 빈 슬롯을 가지고 있는지 체크
const Skill::ProtoType* lpSkillProtoType = CSkillMgr::GetInstance().GetSkillProtoType(wSkillID);
if(NULL == lpSkillProtoType)
{
ERRLOG1(g_Log, "스킬 프로토 타입 얻기 실패. 스킬ID: 0x%04x", wSkillID);
return PktAdminMgr::PktSkillEdit::FAILED_TO_GET_SKILLPROTOTYPE;
}
if(DelSlot.SKILLINFO.wSkill != wSkillID)
{
ERRLOG3(g_Log, "삭제 요청 받은 스킬과 삭제 할 슬롯의 스킬이 일치하지 않습니다."
"슬롯번호: %d , 삭제할 슬롯의 스킬ID: 0x%04x, 삭제 요청 한 스킬ID: 0x%04x",
sDelSlotIndex, DelSlot.SKILLINFO.wSkill, wSkillID);
return PktAdminMgr::PktSkillEdit::FAILED;
}
if(true == lpSkillProtoType->m_bIsClassSkill)
{
ERRLOG0(g_Log, "삭제하려는 스킬이 클래스 스킬입니다.");
return PktAdminMgr::PktSkillEdit::FAILED;
}
// 스킬 슬롯 중간이 비면 한칸씩 앞으로 당겨옴 (중간에 비는 슬롯이 없도록!)
unsigned short sLastSlotIndex = Skill.wSlotNum - 1;
for(unsigned short sSlotIndex = sDelSlotIndex; sSlotIndex < sLastSlotIndex; ++sSlotIndex)
{
Skill.SSlot[sSlotIndex] = Skill.SSlot[sSlotIndex + 1];
}
Skill.SSlot[sLastSlotIndex].SKILLINFO.wSkill = 0;
Skill.SSlot[sLastSlotIndex].SKILLINFO.cSkillLevel = 0;
Skill.SSlot[sLastSlotIndex].SKILLINFO.cLockCount = 0;
Skill.wSkillNum -=
(DelSlot.SKILLINFO.cLockCount * CSkillMgr::MAX_SKILL_LEVEL) + DelSlot.SKILLINFO.cSkillLevel;
Skill.wSlotNum -= 1;
UpdateQuickSlotSkill(DelSlot);
return PktAdminMgr::PktSkillEdit::SUCCESS;
}
return PktAdminMgr::PktSkillEdit::FAILED;
}
bool CModifyCharacter::ChkEmptySlot(SKILL Skill)
{
CString strEmptySlotIndex;
for(unsigned short sSlotIndex = 0; sSlotIndex < Skill.wSlotNum; ++sSlotIndex)
{
if(0 == Skill.SSlot[sSlotIndex].SKILLINFO.wSkill)
{
strEmptySlotIndex.AppendFormat("%d ", sSlotIndex);
}
}
if(!strEmptySlotIndex.IsEmpty())
{
ERRLOG3(g_Log, "스킬 슬롯에 빈슬롯이 있습니다. CID: %u, 슬롯수: %d, 빈슬롯: %s",
GetCID(), Skill.wSlotNum, strEmptySlotIndex);
return true;
}
return false;
}
// 걍 날림 스킬레벨가져오기..
// Return :
// 존재하는 스킬이면 현재 내레벨.. 같은계열의 하위스킬일경우 MaxSkillLevel을...
// 같은 계열스킬중 상위계열이면 0을 리턴..
short CModifyCharacter::GetSkillLevelEX(unsigned short usSkillType, char cLockCount)
{
const Skill::ProtoType* lpSkillProtoType = CSkillMgr::GetInstance().GetSkillProtoType(usSkillType);
if(NULL != lpSkillProtoType)
{
int nMaxSlotNum = m_DBData.m_Skill.wSlotNum;
if(SKILL::MAX_SLOT_NUM >= nMaxSlotNum)
{
for( int nSlot = 0; nSlot < nMaxSlotNum; ++ nSlot )
{
const SKILLSLOT& SkillSlot = m_DBData.m_Skill.SSlot[ nSlot ];
if( SkillSlot.SKILLINFO.wSkill == usSkillType )
{
if( SkillSlot.SKILLINFO.cLockCount == cLockCount )
{
return SkillSlot.SKILLINFO.cSkillLevel;
}
else if( SkillSlot.SKILLINFO.cLockCount > cLockCount )
{
return SKILL::MAX_SKILL_LEVEL;
}
else
{
return 0;
}
}
}
}
}
return -1;
}
bool CModifyCharacter::SetGold(unsigned long dwGold)
{
if(dwGold > ULONG_MAX)
{
return false;
}
m_DBData.m_Info.Gold = dwGold;
return true;
}
// 캐릭터를 잡고 있는 관리자의 Session을 리턴~~
CSession* CModifyCharacter::GetCheckSession( unsigned long dwUID )
{
if( m_dwUID == dwUID )
{
if( NULL != m_lpPacketDispatch )
{
CSession& lpSession = m_lpPacketDispatch->GetSession( );
//if( NULL != lpSession ) return lpSession;
return &lpSession;
}
}
return NULL;
}
// 캐릭터 정보가 변경됬음을 기억해놓자..
void CModifyCharacter::OnChangedInfo( int iMask )
{
m_byChangedInfo |= iMask;
}
// 캐릭터 변경정보를 지운다..
void CModifyCharacter::OffChangedInfo( int iMask )
{
m_byChangedInfo &= iMask;
}
// 캐릭터의 Status
void CModifyCharacter::GetModifyCharStatus(PktAdminMgr::CHAR_STATUS_ST& StatusST)
{
StatusST.m_cFace = m_DBData.m_Info.Face;
StatusST.m_cHair = m_DBData.m_Info.Hair;
StatusST.m_cLevel = m_DBData.m_Info.Level;
StatusST.m_cRace = m_DBData.m_Info.Race;
StatusST.m_cSex = m_DBData.m_Info.Sex;
StatusST.m_dwExp = m_DBData.m_Info.Exp;
StatusST.m_dwFame = m_DBData.m_Info.Fame;
StatusST.m_dwMileage = m_DBData.m_Info.Mileage;
StatusST.m_nClass = m_DBData.m_Info.Class;
StatusST.m_nCON = m_DBData.m_Info.CON;
StatusST.m_nDEX = m_DBData.m_Info.DEX;
StatusST.m_nINT = m_DBData.m_Info.INT;
StatusST.m_nIP = m_DBData.m_Info.IP;
StatusST.m_nSTR = m_DBData.m_Info.STR;
StatusST.m_nWIS = m_DBData.m_Info.WIS;
StatusST.m_cChance = m_DBData.m_Info.Chance;
}
// 캐릭터 Status변경..
bool CModifyCharacter::UpdataStatus(PktAdminMgr::CHAR_STATUS_ST& StatusST)
{
CHAR_INFOST OrgCharInfo;
CopyMemory(&OrgCharInfo, &m_DBData.m_Info, sizeof(CHAR_INFOST));
m_DBData.m_Info.Sex = StatusST.m_cSex;
m_DBData.m_Info.Hair = StatusST.m_cHair;
m_DBData.m_Info.Face = StatusST.m_cFace;
m_DBData.m_Info.Race = StatusST.m_cRace;
m_DBData.m_Info.Class = StatusST.m_nClass;
m_DBData.m_Info.Fame = StatusST.m_dwFame;
m_DBData.m_Info.Mileage = StatusST.m_dwMileage;
m_DBData.m_Info.Level = StatusST.m_cLevel;
m_DBData.m_Info.Exp = StatusST.m_dwExp;
m_DBData.m_Info.IP = StatusST.m_nIP;
m_DBData.m_Info.STR = StatusST.m_nSTR;
m_DBData.m_Info.CON = StatusST.m_nCON;
m_DBData.m_Info.DEX = StatusST.m_nDEX;
m_DBData.m_Info.INT = StatusST.m_nINT;
m_DBData.m_Info.WIS = StatusST.m_nWIS;
m_DBData.m_Info.Chance = StatusST.m_cChance;
m_CreatureStatus.m_nExp = StatusST.m_dwExp;
m_CreatureStatus.m_nLevel = StatusST.m_cLevel;
// Status 계산식을 넣자
if(!CalculateStatusData(false))
{
// 잘못된 Status값
CopyMemory(&m_DBData.m_Info, &OrgCharInfo, sizeof(CHAR_INFOST));
return false;
}
return true;
}
// 캐릭터가 소지하고 있는 아이템을 UID로 검색하여 리턴한다..
// 해당 아이템이 없으면 NULL
Item::CItem* CModifyCharacter::UIDbyItem(unsigned __int64 ItemUID, unsigned char cTakeType)
{
Item::CItemContainer::iterator Itr;
if(cTakeType == TakeType::TS_INVEN) // 인벤토리 아이템
{
Item::CArrayContainer& ArrayContainer = GetInventory();
Itr = ArrayContainer.begin();
for(;Itr != ArrayContainer.end(); ++Itr)
{
if(NULL != (*Itr))
{
if((*Itr)->GetUID() == ItemUID) return (*Itr);
}
}
}
else if( cTakeType == TakeType::TS_EQUIP ) // 장비창 아이템
{
Item::CEquipmentsContainer& EquipContainer = GetEquipments( );
Itr = EquipContainer.begin( );
for(;Itr != EquipContainer.end(); ++Itr )
{
if(NULL != (*Itr))
{
if((*Itr)->GetUID() == ItemUID) return (*Itr);
}
}
}
else if(cTakeType == TakeType::TS_DEPOSIT) // 창고 아이템
{
Item::CDepositContainer& DepositContainer = GetDeposit();
for (unsigned char cTab = 0; cTab < DepositContainer.GetMaxTabNum(); ++cTab)
{
Item::CItemContainer* DepositTabContainer = DepositContainer.GetTab(cTab);
Itr = DepositTabContainer->begin();
for(; Itr != DepositTabContainer->end( ); ++Itr )
{
if( NULL != ( *Itr ) )
{
if( ( *Itr )->GetUID( ) == ItemUID ) return ( *Itr );
}
}
}
}
return NULL;
}
void CModifyCharacter::ChangeName(char* szName)
{
strncpy(m_DBData.m_Info.Name, szName, CHAR_INFOST::MAX_NAME_LEN);
}
// 캐릭터를 편집중인 관리자 계정을 저장한다.
void CModifyCharacter::SetModifyAdmin(char* Account, int Length)
{
strncpy(m_szModifyAdmin, Account, Length);
}
void CModifyCharacter::ParseQuestData()
{
Quest::ExecutingQuest* aryExecutingQuest = GetExecutingQuest();
unsigned short* aryHistoryQuest = GetHistoryQuest();
// 수행중인 퀘스트 목록
int nIndex = 0;
PktQuestDB::ExecutingQuest* lpExecuteQuestPos =
reinterpret_cast<PktQuestDB::ExecutingQuest*>(m_ExtraData.m_Quest.Data);
PktQuestDB::ExecutingQuest* lpExecuteQuestEnd =
reinterpret_cast<PktQuestDB::ExecutingQuest*>(m_ExtraData.m_Quest.Data) +
(m_ExtraData.m_Quest.dwSize / sizeof(PktQuestDB::ExecutingQuest));
for(; lpExecuteQuestPos != lpExecuteQuestEnd; ++lpExecuteQuestPos)
{
Quest::QuestNode* lpQuest = CQuestMgr::GetInstance().GetQuestNode(lpExecuteQuestPos->m_wQuestID);
if (0 != lpQuest && false == lpQuest->CheckNationDependent(GetUserNation()))
{
aryExecutingQuest[nIndex] = Quest::ExecutingQuest(lpExecuteQuestPos->m_wQuestID,
lpExecuteQuestPos->m_cPhase, lpExecuteQuestPos->m_cTriggerCount);
++nIndex;
}
}
nIndex = 0;
// 완료 퀘스트 목록
unsigned short* lpHistoryQuestPos =
reinterpret_cast<unsigned short*>(m_ExtraData.m_History.Data);
unsigned short* lpHistoryQuestEnd =
reinterpret_cast<unsigned short*>(m_ExtraData.m_History.Data) +
(m_ExtraData.m_History.dwSize / sizeof(unsigned short));
for (; lpHistoryQuestPos != lpHistoryQuestEnd; ++lpHistoryQuestPos)
{
Quest::QuestNode* lpQuest = CQuestMgr::GetInstance().GetQuestNode(*lpHistoryQuestPos);
if (0 != lpQuest && false == lpQuest->CheckNationDependent(GetUserNation()))
{
aryHistoryQuest[nIndex] = *lpHistoryQuestPos;
++nIndex;
}
}
// 퀘스트에 의해 받는 영향을 계산
CalculateStatusData(false);
}
void CModifyCharacter::SetQuestData()
{
const int MAX_BUFFER =
sizeof(PktQuestDB) + PktQuestDB::MAX_EXECUTING_QUEST * sizeof(PktQuestDB::ExecutingQuest) +
PktQuestDB::MAX_HISTORY_QUEST * sizeof(unsigned short);
char szBuffer[MAX_BUFFER];
PktQuestDB* lpPktQuestDB = reinterpret_cast<PktQuestDB*>(szBuffer);
lpPktQuestDB->m_dwUID = GetUID();
lpPktQuestDB->m_dwCID = GetCID();
lpPktQuestDB->m_wExecuteQuestSize = 0;
lpPktQuestDB->m_wHistoryQuestSize = 0;
Quest::ExecutingQuest* ExecutingQuest = GetExecutingQuest();
unsigned short *wHistoryQuest = GetHistoryQuest();
int nIndex = 0;
for (nIndex = 0; nIndex < PktQuestDB::MAX_EXECUTING_QUEST; ++nIndex)
{
if (NULL == ExecutingQuest[nIndex].m_QuestNode)
{
break;
}
PktQuestDB::ExecutingQuest* ExecuteQuest =
reinterpret_cast<PktQuestDB::ExecutingQuest*>
(szBuffer + sizeof(PktQuestDB) + lpPktQuestDB->m_wExecuteQuestSize);
ExecuteQuest->m_wQuestID = ExecutingQuest[nIndex].m_QuestNode->m_wQuestID;
ExecuteQuest->m_cPhase = ExecutingQuest[nIndex].m_cPhase;
memcpy(ExecuteQuest->m_cTriggerCount, ExecutingQuest[nIndex].m_cTriggerCount,
sizeof(unsigned char) * PktQuestDB::MAX_TRIGGER);
lpPktQuestDB->m_wExecuteQuestSize += sizeof(PktQuestDB::ExecutingQuest);;
}
for (nIndex = 0; nIndex < PktQuestDB::MAX_HISTORY_QUEST; nIndex++)
{
if (0 == wHistoryQuest[nIndex])
{
break;
}
unsigned short* wHistoryQuestForPkt =
reinterpret_cast<unsigned short *>(szBuffer + sizeof(PktQuestDB) +
lpPktQuestDB->m_wExecuteQuestSize + lpPktQuestDB->m_wHistoryQuestSize);
*wHistoryQuestForPkt = wHistoryQuest[nIndex];
lpPktQuestDB->m_wHistoryQuestSize += sizeof(unsigned short);
}
memset(&m_ExtraData.m_Quest, 0, sizeof(QUEST));
m_ExtraData.m_Quest.dwSize = lpPktQuestDB->m_wExecuteQuestSize;
memcpy(m_ExtraData.m_Quest.Data, lpPktQuestDB + 1, lpPktQuestDB->m_wExecuteQuestSize);
memset(&m_ExtraData.m_History, 0, sizeof(HISTORY));
m_ExtraData.m_History.dwSize = lpPktQuestDB->m_wHistoryQuestSize;
memcpy(m_ExtraData.m_History.Data, reinterpret_cast<char*>(lpPktQuestDB + 1) + lpPktQuestDB->m_wExecuteQuestSize,
lpPktQuestDB->m_wHistoryQuestSize);
}
void CModifyCharacter::RevisionQuestNation()
{
using namespace Creature;
// 양국체제에선 무조건 휴먼은 카르테란트, 아칸은 메르카디아! (퀘스트 파싱할때 필요)
switch(GetRace())
{
case CClass::RaceType::HUMAN:
m_cQuestNation = Creature::KARTERANT;
break;
case CClass::RaceType::AKHAN:
m_cQuestNation = Creature::MERKADIA;
break;
default:
m_cQuestNation = Creature::MAX_NATION;
break;
}
}
// class CModifyItem Down_Cast ----------------------------------------------------------------------------------------------------------------------------------
void CModifyItem::SetUID(unsigned __int64 UID)
{
m_ItemData.m_dwUID = UID;
}
void CModifyItem::SetPrototoypID(unsigned short PrototypeID)
{
m_ItemData.m_usProtoTypeID = PrototypeID;
}

View File

@@ -0,0 +1,291 @@
#ifndef _MODIFY_CHARACTER_H_
#define _MODIFY_CHARACTER_H_
#include < Creature/Character/Character.h >
#include < Network/Protocol/Ryl_AdminMgrProtocol.h >
#include < Pattern/Singleton.h >
// 전처리 ------------------------
class CPacketDispatch;
class CModifyCharacterMgr;
class CBuffer;
class CSession;
//--------------------------------
// Ryl_ItemData.cpp
namespace ItemData
{
// 아이템 좌표를 만든다.
Item::ItemPos MakeItemPos(unsigned char cPos, unsigned char cX, unsigned char cY, unsigned char cZ);
// 어떤위치에 아이템이 존재할까?
inline bool IsArrayContainer(unsigned char cTakePos);
// 아이템을 복사한다.
Item::CItem* CloneItem(Item::CItem* lpSrcItem, PktAdminMgr::CreateItemInfo EquipInfo);
// 한개의 UID에 3명의 캐릭터가 있고 3명의 캐릭터는 1개의 창고를 사용한다..
// 여러 계정의 창고 접근을 막자..
// 창고데이터가 갱신됬을경우 해당 UID에 걸려있는 캐릭터를 작업중인 관리자들에게 창고 정보를 갱신시켜 주자.
class CDepositLock
{
public:
struct DepositInfo
{
unsigned long m_dwCID;
CPacketDispatch* m_lpPacketDispatch;
DepositInfo()
: m_dwCID(0)
, m_lpPacketDispatch(NULL) { ;}
DepositInfo(unsigned long dwCID, CPacketDispatch* lpPacketDispatch)
: m_dwCID(dwCID)
, m_lpPacketDispatch(lpPacketDispatch) { ;}
};
typedef std::map< unsigned long, DepositInfo > isMapDeposit;
typedef isMapDeposit::iterator isDepositPos;
public:
isDepositPos begin() { return m_DepositUser.begin(); }
isDepositPos end() { return m_DepositUser.end(); }
size_t size() { return m_DepositUser.size(); }
bool isUse(unsigned long dwUID, unsigned long dwCID, CPacketDispatch* lpPacketDispatch, bool& bisLock);
void DepositLock(unsigned long dwUID, unsigned long dwCID, CPacketDispatch* lpPacketDispatch);
void DepositUnLock(unsigned long dwUID);
CPacketDispatch* GetDispatch(unsigned long dwUID);
void RemoveAllSelectDispatch(CPacketDispatch* lpPacketDispatch);
bool GetLockInfo(unsigned long dwUID, DepositInfo& Info);
private:
isMapDeposit m_DepositUser;
};
};
// LearnSkill.cpp
// 특정 캐릭터가 습득가능한 스킬을 표시하기 위해 필요한 클래스
// 스킬 스크립트를 로드하여 아이템타입을 제외한 모든 스킬의 ID만 보관
class CSkillID : public CStaticSingleton<CSkillID>
{
public:
typedef std::list<unsigned short> isListSkillUID;
typedef isListSkillUID::iterator isListSkillPos;
~CSkillID() { m_listSkillUID.clear(); }
isListSkillPos begin() { return m_listSkillUID.begin(); }
isListSkillPos end() { return m_listSkillUID.end(); }
void insert(unsigned short SkillUID) { m_listSkillUID.push_back(SkillUID); }
bool ReadSkillScript(char* szScriptName = "./Script/Game/SkillScript.txt");
private:
isListSkillUID m_listSkillUID;
};
// Item::CEquipment 다운 캐스트 클래스 (멤버 변수 추가하지 마시오!)
class CModifyEquipment : public Item::CEquipment
{
public:
void AdjustData(PktAdminMgr::CreateItemInfo EquipInfo)
{
m_cMaxNumOrDurability = EquipInfo.m_cMaxDurability;
m_cMaxSocket = EquipInfo.m_cMaxSocketNum;
m_cUpgradeLevel = EquipInfo.m_cUpgradeLevel;
m_cSeasonRecord = EquipInfo.m_cSeasonRecord;
m_cCoreLevel = EquipInfo.m_cCoreLevel;
for(m_cSocketNum = 0; m_cSocketNum < m_cMaxSocket; ++m_cSocketNum)
{
if (0 == EquipInfo.m_cSocket[m_cSocketNum]) break;
}
CopyMemory(m_cSocket, EquipInfo.m_cSocket,
sizeof(unsigned char) * m_cSocketNum);
CopyMemory(m_usRuneSocket, EquipInfo.m_usRuneSocket,
sizeof(unsigned short) * Item::EquipmentInfo::MAX_RUNE_SOCKET_NUM);
CopyMemory(m_wAttribute, EquipInfo.m_usAttribute,
sizeof(unsigned short) * Item::Attribute::MAX_ATTRIBUTE_NUM);
}
void AddGemAttribute() { ApplyGemAttribute(APPLY); }
void RemoveGemAttribute() { ApplyGemAttribute(REMOVE); }
void AddUpgradeAttribute() { ApplyUpgradeAttribute(APPLY); }
void RemoveUpgradeAttribute() { ApplyUpgradeAttribute(REMOVE); }
void AddRuneAttribute() { ApplyRuneAttribute(APPLY); }
void RemoveRuneAttribute() { ApplyRuneAttribute(REMOVE); }
};
// Item::CItem 다운 캐스트 클래스 (멤버 변수 추가하지 마시오!)
class CModifyItem : public Item::CItem
{
public:
void SetUID(unsigned __int64 UID);
void SetPrototoypID(unsigned short PrototypeID);
};
// 캐릭터 정보 수정을 위한 확장 클래스
class CModifyCharacter : public CCharacter
{
friend CModifyCharacterMgr;
public:
#pragma pack(1)
struct CHAR_EXTRA_DATA
{
CHAR_INFOEX m_CharInfoEX;
QUEST m_Quest;
HISTORY m_History;
CONFIG m_Config;
};
#pragma pack()
enum MASK
{
ON_BASIC = 1, // ON_BASIC 정보 수정
ON_EXTRA = 2, // ON_EXTRA 정보 수정
ON_FRIEND = 4, // ON_FRIEND 정보 수정
ON_BAN = 8, // ON_BAN 정보 수정
ON_STROE12 = 16, // ON_STROE12 정보 수정
ON_STORE34 = 32, // ON_STORE34 정보 수정
OFF_BASIC = 62, // ON_BASIC 정보 없음
OFF_EXTRA = 61, // ON_EXTRA 정보 없음
OFF_FRIEND = 59, // ON_FRIEND 정보 없음
OFF_BAN = 55, // ON_BAN 정보 없음
OFF_STORE12 = 47, // ON_STROE12 정보 없음
OFF_STORE34 = 31, // ON_STORE34 정보 없음
};
CModifyCharacter();
~CModifyCharacter() { }
BYTE m_byChangedInfo;
void SetUID(unsigned long dwUID) { m_dwUID = dwUID; } // 캐릭터 UID 변경
void SetCID(unsigned long dwCID) { m_dwCID = dwCID; } // 캐릭터 CID 변경
void SetUserNation(unsigned char cNation) { m_cQuestNation = cNation; } // 캐릭터 국적 변경
void SetServerGroup(unsigned long dwServerGroup) { m_dwServerGroup = dwServerGroup; } // 서버그룹 변경
void SetOldServerGroup(unsigned char cGroupID) { m_cOldServerGroupID = cGroupID; } // Old 서버 그룹 변경
unsigned long GetServerGroup() { return m_dwServerGroup; } // 현재 서버그룹 얻기
void SetModifyAdmin(char* Account, int Length); // 에디팅중인 관리자 아이디 변경
void SetDispatch(CPacketDispatch* lpPacketDispatch) { m_lpPacketDispatch = lpPacketDispatch; } // 에디팅중인 관리자 Dispatch변경
CPacketDispatch* GetDispatch() { return m_lpPacketDispatch; } // 에디팅중인 관리자의 Dispatch를 가져온다
unsigned short GetMaxHP() { return m_CreatureStatus.m_StatusInfo.m_nMaxHP; } // 캐릭터의 최대 체력
unsigned short GetNowHP() { return m_CreatureStatus.m_nNowHP; } // 캐릭터의 현재 체력
unsigned short GetMaxMP() { return m_CreatureStatus.m_StatusInfo.m_nMaxMP; } // 캐릭터의 최대 마나
unsigned short GetNowMP() { return m_CreatureStatus.m_nNowMP; } // 캐릭터의 현재 마나
char* GetName() { return m_DBData.m_Info.Name; } // 캐릭명 얻기
void ChangeName(char* szName); // 캐릭명 변경
void GetModifyCharStatus(PktAdminMgr::CHAR_STATUS_ST& StatusST); // 스테이터스 정보 얻기
CHAR_EXTRA_DATA& GetExtraData() { return m_ExtraData; } // 기타 정보 얻기
bool UpdataStatus(PktAdminMgr::CHAR_STATUS_ST& StatusST); // 스테이터스 정보 수정
bool SetGold(unsigned long dwGold); // 캐릭터 소지금 변경
Item::CItem* UIDbyItem(unsigned __int64 ItemUID, unsigned char cTakeType); // 아이템UID로 캐릭터 아이템 검색
unsigned short GetMaxSkillPoint(); // 캐릭터가 사용할 수 있는 스킬 포인트
unsigned short GetSkillPoint() { return m_DBData.m_Skill.GetSkillNum(); } // 현재 스킬 수
SKILL& GetSkill() { return m_DBData.m_Skill; } // 캐릭터의 스킬 정보
unsigned char AppendSkill(unsigned short wSkillID, char cLevel, char cLockCount); // 스킬 추가
unsigned char DeleteSkill(unsigned short wSkillID, char cLevel, char cLockCount); // 스킬 삭제
short GetSkillLevelEX(unsigned short usSkillType, char cLockCount); // 스킬 레벨 얻기
bool ChkEmptySlot(SKILL Skill); // 빈 슬롯이 있는지 체크
CHAR_POS& GetLastPos() { return m_DBData.m_Pos; } // 캐릭터의 마지막 위치 얻기
Position& GetCurPos() { return m_CurrentPos; } // 캐릭터의 마지막 위치를 얻기(데이터베이스 정보)
void SetServerID(unsigned long dwServerID) { m_ExtraData.m_CharInfoEX.ServerID = dwServerID; } // 캐릭터의 마지막 서버 아이디(존) 수정
unsigned long GetServerID() { return m_ExtraData.m_CharInfoEX.ServerID; } // 마지막 존 얻기
void Reset(); // 전부 초기화
void OnChangedInfo(int iMask); // 정보가 변경된 섹션 저장
void OffChangedInfo(int iMask); // 정보 변경 섹션을 해제
void SetNextClose() { m_bScheduleClose = true; } // 저장후 캐릭터닫음 설정
bool isClose() { return m_bScheduleClose; } // 캐릭터의 닫힌 상태 여부
void SetClientKey(unsigned long dwClientKey) { m_dwClientRequestKey = dwClientKey; } // 관리자의 클라이언트 키를 변경 ( 클라이언트가 MDI로 계발되었기때문에 있어야함 )
unsigned long GetClientKey() { return m_dwClientRequestKey; } // 관리자의 클라이언트키 가져오기
unsigned char GetOldServerGroupID() { return m_cOldServerGroupID; } // 이전 서버군 ID 얻기 (Part2Selectable)
CSession* GetCheckSession(unsigned long dwUID); // 세션 무결성 체크
void SetSaveState(bool bSave) { m_bSave = bSave; } // 저장임을 알리자
bool GetSaveState() { return m_bSave; } // 저장 중인지 여부
// 중복 아이템 검사 관련
typedef std::set <__int64> ModifyCharItemSerialInfo;
typedef std::vector<__int64> OverlapSerialInfo;
ModifyCharItemSerialInfo m_ModifyCharItemSerialInfo;
OverlapSerialInfo m_OverlapSerialInfo;
void SetOwnCopyItemState(bool IsOwn) { m_bIsOwnCopyItem = IsOwn; } // 복사 아이템 소유여부 셋팅
bool IsOwnCopyItem() { return m_bIsOwnCopyItem; } // 복사 아이템 소유여부
void ParseQuestData();
void SetQuestData();
unsigned char GetUserNation() { return m_cQuestNation; }
char GetChance() { return m_DBData.m_Info.Chance; }
unsigned char GetNameChangeChance() { return m_ExtraData.m_CharInfoEX.cNameChangeCount; }
void SetNameChangeChance(unsigned char cChance) { m_ExtraData.m_CharInfoEX.cNameChangeCount = cChance; }
void RevisionQuestNation(); // 퀘스트 종속성 체크용 국적 설정(2005-11-23 추가)
private:
CPacketDispatch* m_lpPacketDispatch; // 접근중인 관리자 디스패치
unsigned long m_dwServerGroup; // 해당 캐릭터가 존재하는 중계서버의 그룹
char m_szModifyAdmin[40]; // 에디팅중인 관리자 계정명
bool m_bScheduleClose; // 업데이트후 캐릭터 세션을 닫을지 여부
unsigned long m_dwClientRequestKey; // 클라이언트 수정창(문서)의 식별번호
bool m_bSave; // 저장 중인지 여부
bool m_bIsOwnCopyItem; // 복사 아이템 소유 여부
unsigned char m_cQuestNation; // 국적 퀘스트 종속성 검사용
unsigned char m_cOldServerGroupID; // Part2Selectable 타입일때 필요한 정보
CHAR_EXTRA_DATA m_ExtraData; // 캐릭터 정보 구조체 (기타, 퀘스트, 히스토리, 설정)
};
// 정보 열람, 수정 중인 캐릭터 목록 관리
// 각 서버 그룹의 Dispatch가 각각 1개씩 소유
class CModifyCharacterMgr
{
public:
typedef std::map<unsigned long, CModifyCharacter*> isMapCharList;
typedef isMapCharList::iterator iterator;
iterator begin() { return m_mapModifyChar.begin(); }
iterator end() { return m_mapModifyChar.end(); }
size_t size() { return m_mapModifyChar.size(); }
CModifyCharacter* GetCharacter(unsigned long dwCID); // 캐릭터 얻기
CModifyCharacter* InsertChar(unsigned long dwCID); // 캐릭터 등록
bool EraseChar(unsigned long dwCID); // 캐릭터 삭제
void AllRemoveChar(CPacketDispatch* lpPacketDispatch); // lpPacketDispatch를 사용하는 캐릭터를 목록에서 모두 삭제
void isUIDSendAll(unsigned long dwUID, CBuffer* lpBuffer); // UID가 같은 캐릭터 목록의 Dispatch로 패킷 전송
private:
CModifyCharacter* CreateCharacter() { return new CModifyCharacter; }
isMapCharList m_mapModifyChar;
};
#endif

View File

@@ -0,0 +1,79 @@
#include "stdafx.h"
#include "AuthDB.h"
#include "../Parser/ServerInfo.h"
#include <Log/ServerLog.h>
#include <Network/Protocol/Ryl_AdminMgrProtocol.h>
unsigned long CAuthDB::GetUIDFromAccount(char* szAccountName)
{
const char* szNation = CServerInfo::GetInstance().GetValue("NATION");
if (NULL == szNation)
{
ERRLOG0(g_Log, "국가 타입을 얻는데 실패했습니다.");
return 0;
}
char szQuery[MAX_QUERY_LENGTH];
if (0 == strcmp("KOREA", szNation))
{
_snprintf(szQuery, MAX_QUERY_LENGTH,
"SELECT uid, strID FROM TblRylUserInfo WHERE strID = '%s'", szAccountName);
}
else
{
_snprintf(szQuery, MAX_QUERY_LENGTH,
"EXEC dbo.sp_SearchUserAccount NULL, '%s'", szAccountName);
}
unsigned long dwUID = 0;
const int nBufferSize = sizeof(int) + PktAdminMgr::MAX_ACCOUNT;
char szBuffer[nBufferSize];
ZeroMemory(szBuffer, nBufferSize);
if (false == ExecuteQueryGetData(szQuery, szBuffer))
{
ERRLOG2(g_Log, "UID를 얻는데 실패했습니다. Account: %s, Err: %s", szAccountName, GetErrorString());
return 0;
}
memcpy(&dwUID, szBuffer, sizeof(unsigned int));
return dwUID;
}
bool CAuthDB::GetAccountFromUID(unsigned long dwUID, void* lpGetData)
{
const char* szNation = CServerInfo::GetInstance().GetValue("NATION");
if (NULL == szNation)
{
ERRLOG0(g_Log, "국가 타입을 얻는데 실패했습니다.");
return 0;
}
char szQuery[MAX_QUERY_LENGTH];
if (0 == strcmp("KOREA", szNation))
{
_snprintf(szQuery, MAX_QUERY_LENGTH,
"SELECT uid, strID FROM TblRylUserInfo WHERE uid = %u", dwUID);
}
else
{
_snprintf(szQuery, MAX_QUERY_LENGTH,
"EXEC dbo.sp_SearchUserAccount %u, NULL", dwUID);
}
const int nBufferSize = sizeof(int) + PktAdminMgr::MAX_ACCOUNT;
char szBuffer[nBufferSize];
ZeroMemory(szBuffer, nBufferSize);
if (true == ExecuteQueryGetData(szQuery, szBuffer))
{
memcpy(lpGetData, szBuffer + sizeof(int), PktAdminMgr::MAX_ACCOUNT);
return true;
}
ERRLOG2(g_Log, "Account를 얻는데 실패했습니다. UID: %u, Err: %s", dwUID, GetErrorString());
return false;
}

View File

@@ -0,0 +1,20 @@
#ifndef _RYL_AUTHDB_H_
#define _RYL_AUTHDB_H_
#include <BaseLibrary/DB/OLEDB.h>
/*!
\class CAuthDB
인증 DB : 해외 운영 서버일 경우만 사용
*/
class CAuthDB : public OleDB
{
private:
enum SIZE { MAX_QUERY_LENGTH = 5000 };
public:
unsigned long GetUIDFromAccount(char* szAccountName); // 계정명으로 UID 얻기
bool GetAccountFromUID(unsigned long dwUID, void* lpGetData); // UID로 계정명 얻기
};
#endif

View File

@@ -0,0 +1,67 @@
#include "stdafx.h"
#include "BillingDB.h"
#include <Log/ServerLog.h>
bool CBillingDB::CheckLogin(unsigned long dwServerGroup, unsigned long dwUID)
{
// edith 2009.08.14 관심유저 버그수정 (ROW_Activity DB사용)
char szQuery[MAX_QUERY_LENGTH];
_snprintf(szQuery, MAX_QUERY_LENGTH,
"SELECT UID FROM TblCurrentUser WHERE UID = %d AND tinyServerID = %d",
dwUID, dwServerGroup);
unsigned long dwGetUID = 0;
if (true == ExecuteQueryGetData(szQuery, &dwGetUID))
{
if(0 == dwGetUID)
{
// 접속 중이지 않음.
return false;
}
else
{
// 접속 중.
return true;
}
}
return false;
}
unsigned long CBillingDB::GetUIDFromAccount(char* szAccountName)
{
// edith 2009.08.14 관심유저 버그수정 (ROW_Activity DB사용)
char szQuery[MAX_QUERY_LENGTH];
_snprintf(szQuery, MAX_QUERY_LENGTH,
"SELECT TOP 1 UID FROM TblCurrentUser WHERE strClientID = '%s'", szAccountName);
// "SELECT TOP 1 UID FROM TblCurrentUser_log WHERE strClientID = '%s'", szAccountName);
unsigned long dwUID = 0;
if (false == ExecuteQueryGetData(szQuery, &dwUID))
{
ERRLOG2(g_Log, "UID를 얻는데 실패했습니다. Account: %s, Err: %s", szAccountName, GetErrorString());
return 0;
}
return dwUID;
}
bool CBillingDB::GetAccountFromUID(unsigned long dwUID, void* lpGetData)
{
// edith 2009.08.14 관심유저 버그수정 (ROW_Activity DB사용)
char szQuery[MAX_QUERY_LENGTH];
_snprintf(szQuery, MAX_QUERY_LENGTH,
"SELECT TOP 1 strClientID FROM TblCurrentUser WHERE UID = %u", dwUID);
// "SELECT TOP 1 strClientID FROM TblCurrentUser_log WHERE UID = %u", dwUID);
if (false == ExecuteQueryGetData(szQuery, lpGetData))
{
ERRLOG2(g_Log, "Account를 얻는데 실패했습니다. UID: %u, Err: %s", dwUID, GetErrorString());
return false;
}
return true;
}

View File

@@ -0,0 +1,27 @@
#ifndef _RYL_BILLINGDB_H_
#define _RYL_BILLINGDB_H_
#include <BaseLibrary/DB/OLEDB.h>
#include "../Network/Protocol/RYL_AdminMgrProtocol.h"
/*!
\class CBillingDB
과금 DB : 한국 운영서버일 경우만 사용
*/
class CBillingDB : public OleDB
{
private:
enum SIZE { MAX_QUERY_LENGTH = 5000 };
public:
// RYLBillingDB Only!
bool CheckLogin(unsigned long dwServerGroup, unsigned long dwUID); // 해당 계정의 접속 여부 판별
// RYLBillingDB_log Only!
unsigned long GetUIDFromAccount(char* szAccountName); // 계정명으로 UID 얻기
bool GetAccountFromUID(unsigned long dwUID, void* lpGetData); // UID로 계정명 얻기
};
#endif

View File

@@ -0,0 +1,291 @@
#include "stdafx.h"
#include "RYL_GameDB.h"
#include <Log/ServerLog.h>
#include <Network/Packet/PacketStruct/UnifiedCharPacket.h>
// UID에 걸려있는 모든 캐릭터 정보를 가져온다.
bool CGameDB::UIDByCharacterList(unsigned long UID, unsigned int nAgentType,
unsigned int nOldServerID, void* GetData)
{
char* first = reinterpret_cast<char*>(GetData);
unsigned char* lpCount = reinterpret_cast<unsigned char*>(first);
char* In_CharPos = static_cast<char*>(first + 1);
CGameDB::In_UserInfo TblUserInfo;
CGameDB::Out_CharList* lpOut_CharList;
*lpCount = 0;
ZeroMemory(&TblUserInfo, sizeof(CGameDB::In_UserInfo));
if (UnifiedConst::Part2Selectable == nAgentType)
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT Char1, Char2, Char3, Char4, Char5 FROM UserInfo "
"WHERE UID = %d AND OldServerGroupID = %d", UID, nOldServerID);
}
else
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT Char1, Char2, Char3, Char4, Char5 FROM UserInfo "
"WHERE UID = %d AND OldServerGroupID IN (%d, %d)",
UID, UnifiedConst::ROW, UnifiedConst::Part2Unified);
}
if (true == ExecuteQuery(m_szQuery))
{
if(this->GetData(&TblUserInfo))
{
char* CharCID = reinterpret_cast<char*>(&TblUserInfo);
for(int cnt = 0; cnt < SIZE::MAX_CHAR_SLOT; cnt++)
{
unsigned long* CID = reinterpret_cast<unsigned long*>(CharCID + (sizeof(unsigned long) * cnt));
lpOut_CharList = reinterpret_cast<CGameDB::Out_CharList*>(
In_CharPos + ((*lpCount) * sizeof(CGameDB::Out_CharList)));
if(*CID)
{
lpOut_CharList->m_UID = UID;
lpOut_CharList->m_CID = *CID;
CIDByCharacterName(*CID, lpOut_CharList->m_szCharName);
*lpCount += 1;
}
}
return true;
}
}
return false;
}
bool CGameDB::UIDbyUserInfo(unsigned long dwUID, unsigned int nAgentType,
unsigned int nOldServerID, void* GetData)
{
if (UnifiedConst::Part2Selectable == nAgentType)
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT Char1, Char2, Char3, Char4, Char5 FROM UserInfo "
"WHERE UID = %d AND OldServerGroupID = %d", dwUID, nOldServerID);
}
else
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT Char1, Char2, Char3, Char4, Char5 FROM UserInfo "
"WHERE UID = %d AND OldServerGroupID IN (%d, %d)",
dwUID, UnifiedConst::ROW, UnifiedConst::Part2Unified);
}
if (true == ExecuteQuery(m_szQuery))
{
if(this->GetData(GetData))
{
return true;
}
}
return false;
}
bool CGameDB::GetUserNation(unsigned int nAgentType, unsigned long dwUID,
unsigned long dwCID, void* GetData)
{
// CID대신 OldServerGroupID를 받으면 깔끔하지만
// 그렇게 하려면 클라이언트쪽에 애로사항이 꽃핀다.
if (UnifiedConst::Part2Selectable == nAgentType)
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT Nation FROM UserInfo "
"WHERE UID = %d AND (Char1 = %u OR Char2 = %u OR Char3 = %u OR Char4 = %u OR Char5 = %u)",
dwUID, dwCID, dwCID, dwCID, dwCID, dwCID);
}
else
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT Nation FROM UserInfo "
"WHERE UID = %d AND OldServerGroupID IN (%d, %d)",
dwUID, UnifiedConst::ROW, UnifiedConst::Part2Unified);
}
if (true == ExecuteQuery(m_szQuery))
{
if (this->GetData(GetData))
{
return true;
}
}
ERRLOG1(g_Log, "계정 국가 얻기 실패- %s", GetErrorString());
return false;
}
// 캐릭터 이름으로 검색
bool CGameDB::CNameByCharacterList(char* szCharacterName, void* GetData)
{
char* first = reinterpret_cast<char*>(GetData);
unsigned char* lpCount = reinterpret_cast<unsigned char*>(first);
char* In_CharPos = static_cast<char*>(first + 1);
CGameDB::Out_CharList* lpOut_CharList = reinterpret_cast<CGameDB::Out_CharList*>(In_CharPos);
unsigned long dwCID;
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT NewCID FROM TblUnifiedCharList "
"WHERE NewCID IN (SELECT CID FROM CharInfo WHERE Name = '%s') "
"AND (OldServerGroupID <= 15 OR OldServerGroupID IN (%d, %d, %d))",
szCharacterName, UnifiedConst::ROW, UnifiedConst::Part2Unified, UnifiedConst::Part2Selectable);
if (true == ExecuteQuery(m_szQuery))
{
if (this->GetData(&dwCID))
{
*lpCount = 1;
lpOut_CharList = reinterpret_cast<CGameDB::Out_CharList*>(In_CharPos);
lpOut_CharList->m_CID = dwCID;
if(!CIDByCharacterName(dwCID, lpOut_CharList->m_szCharName))
{
return false;
}
if(!CIDByUID(dwCID, &lpOut_CharList->m_UID))
{
return false;
}
}
else
{
return false;
}
}
return true;
}
bool CGameDB::CharacterNameByCID(char* szCharacterName, void* GetData)
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT CID FROM CharInfo WHERE Name = '%s'", szCharacterName);
if(!ExecuteQueryGetData(m_szQuery, GetData))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리-%s, 에러-%s", m_szQuery, GetErrorString());
return false;
}
return true;
}
// CID로 캐릭터 검색
bool CGameDB::CIDByCharacterList(unsigned long CID, void* GetData)
{
char* first = reinterpret_cast<char*>(GetData);
unsigned char* lpCount = reinterpret_cast<unsigned char*>(first);
char* In_CharPos = static_cast<char*>(first + 1);
CGameDB::Out_CharList* lpOut_CharList = reinterpret_cast<CGameDB::Out_CharList*>(In_CharPos);
*lpCount = 1;
lpOut_CharList->m_CID = CID;
if (false == CIDByCharacterName(CID, lpOut_CharList->m_szCharName))
{
return false;
}
if (false == CIDByUID(CID, &lpOut_CharList->m_UID))
{
return false;
}
return true;
}
// CID로 UID검색
bool CGameDB::CIDByUID(unsigned long CID, void* GetData)
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT UID FROM UserInfo WHERE Char1 = %d OR Char2 = %d OR Char3 = %d OR Char4 = %d OR Char5 = %d",
CID, CID, CID, CID, CID);
if (true == ExecuteQuery(m_szQuery))
{
if (this->GetData(GetData))
{
return true;
}
}
GetData = NULL;
return false;
}
// CID로 캐릭터 이름 검색
bool CGameDB::CIDByCharacterName(unsigned long CID, void* GetData)
{
_snprintf(m_szQuery, MAX_QUERY_LENGTH, "SELECT Name FROM CharInfo WHERE CID = %d", CID);
if (true == ExecuteQuery(m_szQuery))
{
if(this->GetData(GetData))
{
return true;
}
}
GetData = NULL;
return false;
}
bool CGameDB::ChangeName(unsigned long dwCID, char* szName)
{
// 중계서버에 캐릭명 변경을 직접 요청하는 방식으로 변경되었음.
/*
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"UPDATE CharInfo SET Name = '%s' WHERE CID = %d", szName, dwCID);
if(!ExecuteQuery(m_szQuery))
{
return false;
}
*/
return true;
}
bool CGameDB::UseCharacterName(char* szName)
{
char result[20];
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT Name FROM CharInfo WHERE Name = '%s'", szName);
if(ExecuteQuery(m_szQuery))
{
if(GetData(result))
{
return true;
}
}
return false;
}
unsigned char CGameDB::GetOldServerGroupID(unsigned long dwCID)
{
unsigned char cOldServerGroupID = 0;
_snprintf(m_szQuery, MAX_QUERY_LENGTH,
"SELECT OldServerGroupID FROM UserInfo"
" WHERE Char1 = %u OR Char2 = %u OR Char3 = %u OR Char4 = %u OR Char5 = %u",
dwCID, dwCID, dwCID, dwCID, dwCID);
if (true == ExecuteQueryGetData(m_szQuery, &cOldServerGroupID))
{
return cOldServerGroupID;
}
return 0;
}

View File

@@ -0,0 +1,55 @@
#ifndef _RYL_GAMEDB_H_
#define _RYL_GAMEDB_H_
#include <DB/DBComponent.h>
/*!
\class CGameDB
게임 데이터 베이스
*/
class CGameDB : public CDBComponent
{
public:
#pragma pack(1)
enum SIZE
{
MAX_CHAR_SLOT = 5
};
struct In_UserInfo
{
unsigned long Char1;
unsigned long Char2;
unsigned long Char3;
unsigned long Char4;
unsigned long Char5;
};
struct Out_CharList
{
char m_szCharName[16];
unsigned long m_UID;
unsigned long m_CID;
};
#pragma pack()
public:
bool CIDByCharacterList(unsigned long CID, void* GetData); // 단일 캐릭터만 나옴
bool CNameByCharacterList(char* szCharacterName, void* GetData); // 단일 캐릭터만 나옴
bool CIDByUID(unsigned long CID, void* GetData); // CID로 UID 얻기
bool CharacterNameByCID(char* szCharacterName, void* GetData); // 캐릭터 이름으로 CID 얻기
bool CIDByCharacterName(unsigned long CID, void* GetData); // CID로 캐릭터 이름 얻기
bool UseCharacterName(char* szName); // 해당 캐릭명이 사용중인지 판별
bool ChangeName(unsigned long dwCID, char* szName); // 캐릭터 이름 변경
// Part2Selectable 타입의 영향을 받는 루틴
bool UIDByCharacterList(unsigned long UID, unsigned int nAgentType, unsigned int nOldServerID, void* GetData); // 복수의 캐릭터가 있을수 있음
bool UIDbyUserInfo(unsigned long dwUID, unsigned int nAgentType, unsigned int nOldServerID, void* GetData); // UID로 캐릭터 리스트 가져오기
bool GetUserNation(unsigned int nAgentType, unsigned long dwUID, unsigned long dwCID, void* GetData); // 계정 국가 얻기
unsigned char GetOldServerGroupID(unsigned long dwCID); // 해당 CID가 연결되있는 UserInfo의 OldServerGroupID 얻기
private:
char m_szQuery[MAX_QUERY_LENGTH];
};
#endif

View File

@@ -0,0 +1,522 @@
#include "stdafx.h"
#include <Log/ServerLog.h>
#include <Parser/ServerInfo.h>
#include <DBComponent/Ryl_AdminMgrDB.h>
#include <Network/Protocol/Ryl_AdminMgrProtocol.h>
CDBAdminTool& CDBAdminTool::GetInstance()
{
static CDBAdminTool dbAdminTool;
return dbAdminTool;
}
bool CDBAdminTool::ConnectAdminToolDB()
{
const int MAX_BUFFER = 255;
CServerInfo& ServerInfoTXT = CServerInfo::GetInstance();
if(!ServerInfoTXT.Reload())
{
ERRLOG0(g_Log, "서버 셋업 파일 로드 실패");
return false;
}
const char* DBAddress = ServerInfoTXT.GetValue("ADMINTOOL_DB_IP");
const char* DBName = ServerInfoTXT.GetValue("ADMINTOOL_DB_NAME");
const char* DBAccount = ServerInfoTXT.GetValue("ADMINTOOL_DB_ACCOUNT");
const char* DBPass = ServerInfoTXT.GetValue("ADMINTOOL_DB_PASS");
char szDBAddress[MAX_BUFFER];
char szDBName[MAX_BUFFER];
char szDBAccount[MAX_BUFFER];
char szDBPass[MAX_BUFFER];
strncpy(szDBAddress, DBAddress, MAX_BUFFER); szDBAddress[MAX_BUFFER - 1] = 0;
strncpy(szDBName, DBName, MAX_BUFFER); szDBName[MAX_BUFFER - 1] = 0;
strncpy(szDBAccount, DBAccount, MAX_BUFFER); szDBAccount[MAX_BUFFER - 1] = 0;
strncpy(szDBPass, DBPass, MAX_BUFFER); szDBPass[MAX_BUFFER - 1] = 0;
if(!ConnectSQLServer(szDBAddress, szDBName, szDBAccount, szDBPass, OleDB::ConnType_MSSQL))
{
ERRLOG4(g_Log, "운영DB 연결 실패. %s/%s/%s/%s",
szDBAddress, szDBName, szDBAccount, szDBPass);
return false;
}
return true;
}
bool CDBAdminTool::UpdateZoneList(unsigned int UID, char* In_Data)
{
_snprintf(m_szQry, MAX_QUERY_LENGTH, "SELECT binZone FROM TblToolAdmin WHERE uid=%d", UID);
if(ExecuteQuery(m_szQry, OleDB::Rowset_Update))
{
if(!SetBinaryData(1, (OleDB::LPSET_BINARY)In_Data))
{
ERRLOG0(g_Log, "바이너리 데이터 셋팅 실패");
return false;
}
}
return true;
}
bool CDBAdminTool::GetZoneList(unsigned int UID, char* Out_Data)
{
_snprintf(m_szQry, MAX_QUERY_LENGTH, "SELECT binZone FROM TblToolAdmin WHERE uid=%d", UID);
if(!ExecuteQueryGetData(m_szQry, Out_Data))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리-%s, 에러-%s", m_szQry, GetErrorString());
return false;
}
return true;
}
// 관리자 계정 로그인
BYTE CDBAdminTool::Login(char* szAccount, char* szPassword)
{
char szGetedPassword[PktAdminMgr::MAX_PASSWORD];
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"SELECT strPasswd FROM TblToolAdmin WHERE strAdminID='%s'", szAccount);
ZeroMemory(szGetedPassword, PktAdminMgr::MAX_PASSWORD);
if(!ExecuteQueryGetData(m_szQry, (void*)szGetedPassword))
{
// 계정이 존재 하지 않음
return PktAdminMgr::PktResult::Err_Account;
}
if(NULL != szGetedPassword)
{
if(!stricmp(szGetedPassword, szPassword))
{
// 로그인 성공
return PktAdminMgr::PktResult::Success_Login;
}
else
{
// 패스워드 다름
return PktAdminMgr::PktResult::Err_Passwd;
}
}
return PktAdminMgr::PktResult::Err_Unknown;
}
// 해당 관리자 계정 접속 아이피 체크
BYTE CDBAdminTool::CheckIP(char* AdminID, char* szIP)
{
char strIP[16];
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"SELECT strIP FROM TblToolAdmin WHERE strAdminID='%s'", AdminID);
ZeroMemory(strIP, sizeof(strIP));
if(!ExecuteQueryGetData(m_szQry, (void*)strIP))
{
// 해당 ID 에대한 값을 찾을수 없거나 데이터 베이스 에러
return PktAdminMgr::PktResult::Err_Database;
}
if(NULL != strIP)
{
if(!stricmp(szIP, strIP))
{
// 성공
return PktAdminMgr::PktResult::Success_ConnectIP;
}
else
{
// 등록되어 있는 아이피가 아님
return PktAdminMgr::PktResult::Err_ConnectIP;
}
}
else
{
return PktAdminMgr::PktResult::Err_Database;
}
return PktAdminMgr::PktResult::Err_Unknown;
}
// 선택아이디가 있냐? 없냐?
bool CDBAdminTool::AccountCheck(char* AdminID)
{
char strAdminID[20];
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"SELECT strAdminID FROM TblToolAdmin WHERE strAdminID='%s'", AdminID);
ZeroMemory(strAdminID, sizeof(strAdminID));
if(!ExecuteQueryGetData(m_szQry, (void*)strAdminID))
{
return true;
}
return false;
}
// 로그를 시작..
bool CDBAdminTool::StartupLog(unsigned int UID, char* UseIP)
{
char szDate[30];
if(!UID) return false;
if(GetDate(szDate))
{
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"INSERT INTO TblLog(UID, Login, UseIP) VALUES(%d, '%s', '%s')", UID, szDate, UseIP);
if(!ExecuteQuery(m_szQry))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리- %s, Err- %s",
m_szQry, GetErrorString());
return false;
}
}
return true;
}
// 로그를 마친다
bool CDBAdminTool::EndLog(unsigned int UID)
{
char szDate[30];
int LogID;
if(!UID) return false;
if(GetDate(szDate))
{
if((LogID = GetNowLogID(UID)) > 0)
{
return UpdateLogoutDate(LogID, szDate);
}
}
return false;
}
// 관리자의 UID를 가져온다.
int CDBAdminTool::GetMyUID(char* szAccount)
{
int UID;
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"SELECT UID FROM TblToolAdmin WHERE strAdminID='%s'", szAccount);
if(ExecuteQuery(m_szQry))
{
if(GetData(&UID))
{
return UID;
}
}
return -1;
}
// 관리자 계정삭제.
bool CDBAdminTool::DelAdmin( char* AdminID )
{
_snprintf(m_szQry, MAX_QUERY_LENGTH, "DELETE TblToolAdmin WHERE strAdminID='%s'", AdminID);
if(!ExecuteQuery(m_szQry))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리- %s, Err- %s",
m_szQry, GetErrorString());
return false;
}
return true;
}
// 로그를 마친다.
bool CDBAdminTool::UpdateExitLog( unsigned int LogID, char* szExitLog )
{
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"UPDATE TblLog SET UseMsg='%s' WHERE LogID=%d", szExitLog, LogID);
if(!ExecuteQuery(m_szQry))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리- %s, Err- %s",
m_szQry, GetErrorString());
return false;
}
return true;
}
// 관리자 레벨변경
bool CDBAdminTool::UpdateLevel(PktAdminMgr::PktUpdateLevel* UpdateLev)
{
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"UPDATE TblToolAdmin SET strLevel='%c' WHERE strAdminID='%s'",
UpdateLev->m_szLevel, UpdateLev->m_szAccount);
if(!ExecuteQuery(m_szQry))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리- %s, Err- %s",
m_szQry, GetErrorString());
return false;
}
return true;
}
// 관리자 접속 아이피 변경
bool CDBAdminTool::UpdateIP(PktAdminMgr::PktUpdateIP* UpdateIP)
{
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"UPDATE TblToolAdmin SET strIP = '%s' WHERE strAdminID = '%s'",
UpdateIP->m_szIP, UpdateIP->m_szAccount);
if(!ExecuteQuery(m_szQry))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리- %s, Err- %s",
m_szQry, GetErrorString());
return false;
}
return true;
}
// 관리자 로그아웃날자 변경
bool CDBAdminTool::UpdateLogoutDate(int LogID, char* szDate)
{
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"UPDATE TblLog SET Logout='%s' WHERE LogID=%d", szDate, LogID);
if(!ExecuteQuery(m_szQry))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리- %s, Err- %s",
m_szQry, GetErrorString());
return false;
}
return true;
}
// 데이터 베이스에서 날자를 가져온다
bool CDBAdminTool::GetDate(char* DateTime)
{
if(ExecuteQuery("SELECT CONVERT(varchar(30), getdate(), 120)"))
{
if(GetData(DateTime))
{
return true;
}
}
return false;
}
// 접속 할때 부여받은 로그 ID 얻기
int CDBAdminTool::GetNowLogID(unsigned int UID)
{
int GetLogID = 0;
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"SELECT LogID FROM TblLog WHERE UID = %d ORDER BY LogID DESC", UID);
if(ExecuteQuery(m_szQry))
{
if(GetData(&GetLogID))
{
return GetLogID;
}
}
ERRLOG1(g_Log, "로그 ID를 얻는데 실패했습니다. Err- %s", GetErrorString());
return -1;
}
// 패스워드 변경
bool CDBAdminTool::UpdatePasswd( PktAdminMgr::PktUpdatePasswd* UpdatePwd )
{
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"UPDATE TblToolAdmin SET strPasswd = '%s' WHERE strAdminID = '%s'",
UpdatePwd->m_szPasswd, UpdatePwd->m_szAccount);
if(!ExecuteQuery(m_szQry))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리- %s, Err- %s",
m_szQry, GetErrorString());
return false;
}
return true;
}
// 새로운 관리자 계정을 생성한다.
BYTE CDBAdminTool::NewAdmin(PktAdminMgr::PktNewAdmin* NewAdmin)
{
if(AccountCheck(NewAdmin->m_szAccount)) // 사용 여부 체크
{
_snprintf(m_szQry, MAX_QUERY_LENGTH,
"INSERT INTO TblToolAdmin(strAdminID, strPasswd, strLevel, strName, strIP) VALUES('%s', '%s', '%c', '%s', '%s')",
NewAdmin->m_szAccount, NewAdmin->m_szPasswd, NewAdmin->m_szLev, NewAdmin->m_szName, NewAdmin->m_szIP);
if(!ExecuteQuery(m_szQry))
{
ERRLOG2(g_Log, "쿼리 실패. 쿼리- %s, Err- %s",
m_szQry, GetErrorString());
return PktAdminMgr::PktResult::Err_Database; // 켁~
}
return PktAdminMgr::PktResult::Success_NewAdmin; // 만들기 성공~
}
else
{
return PktAdminMgr::PktResult::Err_OverlapID; // 씨또 중복아이디다.
}
return PktAdminMgr::PktResult::Err_Unknown; // ㅡ.ㅡ;
}
bool CDBAdminTool::AddBlockUser(PktAdminMgr::PktAddBlockUser* lpBlock, char* lpAdminName, char* szClientID)
{
char szQuery[MAX_QUERY_LENGTH];
_snprintf(szQuery, MAX_QUERY_LENGTH,
"dbo.CMS_DoingRestraintChar '%d', '%d', '%s', '%s', '%d', '%d', '%s', '%s', '%s'",
lpBlock->m_cServerGroup, lpBlock->m_dwUID, szClientID, lpBlock->m_szCharacterName,
lpBlock->m_cBlockTarget, lpBlock->m_cBlockTerm, lpBlock->m_szBlockFinishDateTime,
lpAdminName, lpBlock->m_szDescription);
unsigned long dwResult = 0;
if (false == ExecuteQueryGetData(szQuery, &dwResult))
{
ERRLOG2(g_Log, "쿼리 실패. query- %s, Err- %s", szQuery, GetErrorString());
return false;
}
if(0 < dwResult)
{
return true;
}
return false;
}
bool CDBAdminTool::DelBlockUser(PktAdminMgr::PktDelBlockUser* lpDelBlock)
{
char szQuery[MAX_QUERY_LENGTH];
_snprintf(szQuery, MAX_QUERY_LENGTH, "dbo.USPDeleteRestraintChar '%d', '%d'",
lpDelBlock->m_cServerGroup, lpDelBlock->m_nidx);
unsigned long dwResult = 0;
if (false == ExecuteQueryGetData(szQuery, &dwResult))
{
ERRLOG2(g_Log, "쿼리 실패. query- %s, Err- %s", szQuery, GetErrorString());
return false;
}
if(0 < dwResult)
{
return true;
}
return false;
}
bool CDBAdminTool::InsertGMLogMsg(PktAdminMgr::PktGMLogMsg* lpPktGMLogMsg, char* szAdminID)
{
char szQuery[MAX_QUERY_LENGTH];
_snprintf(szQuery, MAX_QUERY_LENGTH,
"INSERT INTO TblGMLogMsg(UID, CID, ServerGroupID, LogMsg, AdminID) VALUES(%u, %u, %u, '%s', '%s')",
lpPktGMLogMsg->m_dwUID, lpPktGMLogMsg->m_dwCID, lpPktGMLogMsg->m_dwServerGroup,
lpPktGMLogMsg->m_szLogMsg, szAdminID);
if (false == ExecuteQuery(szQuery))
{
ERRLOG2(g_Log, "운영자 로그 삽입 실패. 쿼리- %s, Err- %s", szQuery, GetErrorString());
return false;
}
return true;
}
bool CDBAdminTool::UpdateGMLogMsg(PktAdminMgr::PktGMLogMsg* lpPktGMLogMsg, char* szAdminID)
{
char szQuery[MAX_QUERY_LENGTH];
_snprintf(szQuery, MAX_QUERY_LENGTH,
"UPDATE TblGMLogMsg SET LogMsg = '%s', AdminID = '%s'"
" WHERE LogID = %u AND UID = %u AND CID = %u AND ServerGroupID = %u",
lpPktGMLogMsg->m_szLogMsg, szAdminID, lpPktGMLogMsg->m_dwLogID, lpPktGMLogMsg->m_dwUID,
lpPktGMLogMsg->m_dwCID, lpPktGMLogMsg->m_dwServerGroup);
if (false == ExecuteQuery(szQuery))
{
ERRLOG2(g_Log, "운영자 로그 업데이트 실패. 쿼리- %s, Err- %s", szQuery, GetErrorString());
return false;
}
return true;
}
bool CDBAdminTool::DeleteGMLogMsg(PktAdminMgr::PktGMLogMsg* lpPktGMLogMsg)
{
char szQuery[MAX_QUERY_LENGTH];
_snprintf(szQuery, MAX_QUERY_LENGTH,
"INSERT INTO TblGMLogMsg_Log(LogID, UID, CID, ServerGroupID, EditDate, LogMsg, AdminID) "
"SELECT LogID, UID, CID, ServerGroupID, EditDate, LogMsg, AdminID FROM TblGMLogMsg WHERE LogID = %u",
lpPktGMLogMsg->m_dwLogID);
if (false == ExecuteQuery(szQuery))
{
ERRLOG2(g_Log, "운영자 로그 삭제 실패(로그 남기기). 쿼리- %s, Err- %s", szQuery, GetErrorString());
return false;
}
_snprintf(szQuery, MAX_QUERY_LENGTH,
"DELETE FROM TblGMLogMsg WHERE LogID = %u", lpPktGMLogMsg->m_dwLogID);
if (false == ExecuteQuery(szQuery))
{
ERRLOG2(g_Log, "운영자 로그 삭제 실패(로그 삭제). 쿼리- %s, Err- %s", szQuery, GetErrorString());
return false;
}
return true;
}
bool CDBAdminTool::IsExistLogMsg(PktAdminMgr::PktGMLogMsg* lpPktGMLogMsg)
{
char szQuery[MAX_QUERY_LENGTH];
if (0 == lpPktGMLogMsg->m_dwCID)
{
_snprintf(szQuery, MAX_QUERY_LENGTH,
"SELECT TOP 1 LogID FROM TblGMLogMsg WHERE UID = %u AND CID = 0 AND ServerGroupID = %u",
lpPktGMLogMsg->m_dwUID, lpPktGMLogMsg->m_dwServerGroup);
}
else
{
_snprintf(szQuery, MAX_QUERY_LENGTH,
"SELECT TOP 1 LogID FROM TblGMLogMsg WHERE CID = %u AND ServerGroupID = %u",
lpPktGMLogMsg->m_dwCID, lpPktGMLogMsg->m_dwServerGroup);
}
unsigned long dwLogID = 0;
if (false == ExecuteQueryGetData(szQuery, &dwLogID))
{
return false;
}
if (0 == dwLogID)
{
return false;
}
return true;
}

View File

@@ -0,0 +1,129 @@
#ifndef _RYL_ADMIN_MGR_DB_H_
#define _RYL_ADMIN_MGR_DB_H_
#include <RylServerLibrary/DB/DBComponent.h>
// 쿼리 모음
namespace QUERYZ
{
const char LoginInfo[] = "SELECT uid, strAdminID, strPasswd, strLevel, strName, strIP, CONVERT(varchar(11),dateRegit,102) FROM TblToolAdmin WHERE strAdminID = '%s'";
const char NewAdminAck[] = "SELECT strAdminID, strName, strIP, convert(varchar(11),dateRegit,102), strLevel FROM TblToolAdmin WHERE strAdminID='%s'";
const char LoginList[] = "SELECT LogID, CONVERT( varchar(20), Login, 120 ), CONVERT(varchar(20), Logout, 120 ), UseIP FROM TblLog WHERE UID=%d" ;
const char DetailLog[] = "SELECT DetailLogID, CONVERT(varchar(20), UpdateDate, 120), UpdateType FROM TblDetailLog WHERE LogID=%d" ;
const char ExitLog[] = "SELECT UseMsg FROM TblLog WHERE LogID = %d";
const char AdminList[] = "SELECT strAdminID, strName, strIP, CONVERT(varchar(11),dateRegit,102), strLevel FROM TblToolAdmin" ;
const char InsertDetailLog[] = "INSERT INTO TblDetailLog(LogID, UpdateType, Before, After) VALUES(%d, %d, '%s', '%s')";
const char BeforeAfter[] = "SELECT Before, After FROM TblDetailLog WHERE DetailLogID=%d" ;
const char GetLevel[] = "SELECT strLevel FROM TblToolAdmin WHERE strAdminID='%s'" ;
const char GetIP[] = "SELECT strIP FROM TblToolAdmin WHERE strAdminID='%s'" ;
const char GetPassword[] = "SELECT strPasswd FROM TblToolAdmin WHERE strAdminID='%s'" ;
const char GetDelHistory[] = "SELECT intCID, intUID, NewServerGroupID, OldServerGroupID, CONVERT(varchar(20), dateInsertTime, 120), CONVERT(varchar(20), dateDeleteTime, 120), Name, CAST(Level as INT), Gold FROM TblCharDelHistory JOIN CharInfo ON TblCharDelHistory.intCID = CharInfo.CID WHERE %s=%d AND NewServerGroupID = %u";
const char GetGuildInfo[] = "SELECT A.nGuildID, CAST(OldServerGroupID AS INT), strGuildName, CAST(tnGuildLevel AS INT), nGuildFame, nGuildGold, CAST(tnNationType as INT) FROM TblGuildInfo A JOIN TblGuildMember B ON A.nGuildID =B.nGuildID %s GROUP BY A.nGuildID, CAST(OldServerGroupID AS INT), strGuildName, CAST(tnGuildLevel as INT), nGuildFame, nGuildGold, CAST(tnNationType as INT)";
const char GetFortInfo[] = "SELECT A.nCampID, A.nGuildID, B.strGuildName, A.nHP, A.tnZone, A.tnChannel, A.snObjectType, A.tnState, A.tnSubState, A.tnUpgradeStep,"
"CONVERT(varchar(20), RemainTime, 120), CONVERT(varchar(20), LastUseTime, 120), A.fPosX, A.fPosY, A.fPosZ, A.tnMaterial, A.tnSiegeCount, A.bRight "
"FROM TblCampInfo A INNER JOIN TblGuildInfo B ON A.nGuildID = B.nGuildID %s"
"GROUP BY A.nCampID, A.nGuildID, B.strGuildName, A.nHP, A.tnZone, A.tnChannel, A.snObjectType,A.tnState, A.tnSubState, A.tnUpgradeStep,"
"CONVERT(varchar(20), RemainTime, 120), CONVERT(varchar(20), LastUseTime, 120), A.bRight, A.fPosX, A.fPosY, A.fPosZ, A.tnMaterial, A.tnSiegeCount";
const char GetMiningCamp[] = "SELECT * FROM TblCampMineralInfo %s";
const char GetShopCamp[] = "SELECT * FROM TblCampShopInfo %s";
const char GetCastleInfo[] = "SELECT * FROM TblCastleInfo %s";
const char GetCastleCreatureInfo[] = "SELECT nCreatureID, nCastleID, nOwnerID, nHP, snObjectType, fDirection, tnState, tnSubState, tnUpgradeStep, tnUpgradeType, "
"CONVERT(varchar(20), RemainTime, 120), CONVERT(varchar(20), LastUseTime, 120), fPosX, fPosY, fPosZ FROM TblCastleCreatureInfo %s";
const char GetGuildMemberList[] = "SELECT nGuildID, nCID, nPosition, nPositionInGuild, CONVERT(varchar(20), tLeaveGuildTime, 120), Name, CAST(Level as INT), Fame, Class, Gold FROM TblGuildMember JOIN CharInfo ON TblGuildMember.nCID = CharInfo.CID WHERE nGuildID = %s";
const char GetGuildRestoreData[] = "SELECT nGuildID, strGuildName, nGuildGold, CONVERT(varchar(20), tDeleteTime, 120) FROM TblGuildRestoreData";
// edith 2009.08.14 관심유저 버그수정 (ROW_Activity DB사용)
const char GetUserBillingLog[] = "SELECT strClientid, UID, CAST(tinyServerID AS INT), CONVERT(VARCHAR(20), FirstLoginTime, 120), CONVERT(VARCHAR(20), LogoutTime, 120), CAST(strIP AS VARCHAR(16)) FROM TblCurrentUser WHERE %s ORDER BY FirstLoginTime";
// const char GetUserBillingLog[] = "SELECT strClientid, UID, CAST(tinyServerID AS INT), CONVERT(VARCHAR(20), FirstLoginTime, 120), CONVERT(VARCHAR(20), LogoutTime, 120), CAST(strIP AS VARCHAR(16)) FROM TblCurrentUser_Log WHERE %s ORDER BY FirstLoginTime";
};
// 단순 참조용
namespace PktAdminMgr
{
struct PktNewAdmin;
struct PktUpdateLevel;
struct PktUpdateIP;
struct PktUpdatePasswd;
struct PktAddBlockUser;
struct PktDelBlockUser;
struct PktInterestedUser;
struct PktGMLogMsg;
};
/*!
\class CDBAdminTool
운영툴 데이터 베이스
*/
class CDBAdminTool : public CDBComponent
{
public:
#pragma pack(1)
// 관리자 아이템 창고정보
struct StoreInfo
{
enum TYPE
{
MAX_OWNER = 20,
MAX_ITEM_NAME = 32
};
unsigned char cServer;
unsigned char szOwner[MAX_OWNER];
unsigned char szItemName[MAX_ITEM_NAME];
};
// 관리자 아이템 창고정보
struct ItemInfo
{
enum TYPE
{
MAX_ITEM_ATTRIB = 90,
};
unsigned long dwLength;
char ItemAttrib[MAX_ITEM_ATTRIB];
};
#pragma pack()
public:
static CDBAdminTool& GetInstance();
bool ConnectAdminToolDB(); // SQL서버 접속
BYTE Login(char* szAccount, char* szPassword); // 로그인
BYTE CheckIP(char* AdminID, char* szIP); // 아이피 체크
bool AccountCheck(char* AdminID); // 중복여부 검사
BYTE NewAdmin(PktAdminMgr::PktNewAdmin* NewAdmin); // 새로운 계정 생성
bool DelAdmin(char* AdminID); // 계정 삭제
bool UpdateLevel(PktAdminMgr::PktUpdateLevel* UpdateLev); // 계정 등급 변경
bool UpdateIP(PktAdminMgr::PktUpdateIP* UpdateIP); // 계정 접속 IP변경
bool UpdatePasswd(PktAdminMgr::PktUpdatePasswd* UpdatePwd); // 계정 패스워드 변경
bool GetDate(char* DateTime); // 시간을 가져온다
bool StartupLog(unsigned int UID, char* UseIP); // 로그인함과 동시에 호출. 기본 셋팅
bool EndLog(unsigned int UID); // 로그아웃 정보 기록
int GetMyUID(char* szAccount); // 해당계정의 UID를 가져온다
int GetNowLogID(unsigned int UID); // 현재 사용중인 TblLog의 LogID를 가져온다
bool UpdateLogoutDate(int LogID, char* szDate); // 로그아웃한 날짜와 시간
bool UpdateExitLog(unsigned int LogID, char* szExitLog); // 사용사유 업데이트
bool UpdateZoneList(unsigned int UID, char* In_Data); // 존 정보 저장
bool GetZoneList(unsigned int UID, char* Out_Data); // 존 정보 가져오기
// 블럭
bool AddBlockUser(PktAdminMgr::PktAddBlockUser* lpBlock, char* lpAdminName, char* szClientID); // 블럭
bool DelBlockUser(PktAdminMgr::PktDelBlockUser* lpDelBlock); // 블럭 해제
// GM 로그 메세지 남기기
bool IsExistLogMsg(PktAdminMgr::PktGMLogMsg* lpPktGMLogMsg);
bool InsertGMLogMsg(PktAdminMgr::PktGMLogMsg* lpPktGMLogMsg, char* szAdminID);
bool UpdateGMLogMsg(PktAdminMgr::PktGMLogMsg* lpPktGMLogMsg, char* szAdminID);
bool DeleteGMLogMsg(PktAdminMgr::PktGMLogMsg* lpPktGMLogMsg);
private:
CDBAdminTool() { ;}
virtual ~CDBAdminTool() { ;}
char m_szQry[MAX_QUERY_LENGTH];
};
#endif

View File

@@ -0,0 +1,184 @@
#include "stdafx.h"
#include "Ryl_DetailLog.h"
#include "DBComponent/Ryl_AdminMgrDB.h"
#include <Network/Packet/PacketBase.h>
#include <Log/ServerLog.h>
char CDetailLog::m_szAfter [1024];
char CDetailLog::m_szBefore[1024];
char CDetailLog::m_szQuery [5000];
CDetailLog::CDetailLog()
{
for(int nCMD = 0; nCMD < PktAdminMgr::PktCMD::PktEnd; ++nCMD)
{
PktLog[nCMD] = PktEmpty;
}
PktLog[PktAdminMgr::PktCMD::PktNewAdmin] = PktNewAdmin;
PktLog[PktAdminMgr::PktCMD::PktDelAdmin] = PktDelAdmin;
PktLog[PktAdminMgr::PktCMD::PktUpdateLevel] = PktUpdateLevel;
PktLog[PktAdminMgr::PktCMD::PktUpdateIP] = PktUpdateIP;
PktLog[PktAdminMgr::PktCMD::PktUpdatePasswd] = PktUpdatePasswd;
}
void CDetailLog::SetBefore(char* lpBefore, ...)
{
va_list Arguments;
va_start_ext(Arguments, lpBefore);
_vsntprintf(CDetailLog::m_szBefore, sizeof(m_szBefore), lpBefore, Arguments);
va_end(Arguments);
}
void CDetailLog::SetAfter(char* lpAfter, ...)
{
va_list Arguments;
va_start_ext(Arguments, lpAfter);
_vsntprintf(CDetailLog::m_szAfter, sizeof(m_szAfter), lpAfter, Arguments);
va_end(Arguments);
}
void CDetailLog::InsertLog(unsigned int LogID)
{
_snprintf(CDetailLog::m_szQuery, CDBAdminTool::MAX_QUERY_LENGTH,
QUERYZ::InsertDetailLog, LogID, TYPE_ADMIN, CDetailLog::m_szBefore, CDetailLog::m_szAfter);
}
void CDetailLog::PktNewAdmin(LOG_METHOD)
{
PktAdminMgr::PktNewAdmin* lpPktNewAdmin =
static_cast<PktAdminMgr::PktNewAdmin*>(lpPktBase);
int len;
_snprintf(CDetailLog::m_szBefore, sizeof(CDetailLog::m_szBefore), "not exist contents");
_snprintf(CDetailLog::m_szAfter, sizeof(CDetailLog::m_szAfter),
"[Tool Admin Account Registration]\r\n"
"Account: %s\r\nPass: %s\r\nName: %s\r\nIP: %s\r\nLevel: %c",
lpPktNewAdmin->m_szAccount, lpPktNewAdmin->m_szPasswd, lpPktNewAdmin->m_szName,
lpPktNewAdmin->m_szIP, lpPktNewAdmin->m_szLev );
_snprintf(CDetailLog::m_szQuery, CDBAdminTool::MAX_QUERY_LENGTH,
QUERYZ::InsertDetailLog, LogID, TYPE_ADMIN, CDetailLog::m_szBefore, CDetailLog::m_szAfter);
len = strlen(CDetailLog::m_szAfter);
}
void CDetailLog::PktDelAdmin(LOG_METHOD)
{
PktAdminMgr::PktDelAdmin* lpPktDelAdmin =
static_cast<PktAdminMgr::PktDelAdmin*>(lpPktBase);
_snprintf(CDetailLog::m_szBefore, sizeof(CDetailLog::m_szBefore), "not exist contents" );
_snprintf(CDetailLog::m_szAfter, sizeof(CDetailLog::m_szAfter),
"[Tool Admin Account Delete]\r\nDeleted Account: %s", lpPktDelAdmin->m_szAccount);
_snprintf(CDetailLog::m_szQuery, CDBAdminTool::MAX_QUERY_LENGTH,
QUERYZ::InsertDetailLog, LogID, TYPE_ADMIN, CDetailLog::m_szBefore, CDetailLog::m_szAfter);
}
void CDetailLog::PktUpdateLevel(LOG_METHOD)
{
PktAdminMgr::PktUpdateLevel* lpPktUpdateLevel =
static_cast<PktAdminMgr::PktUpdateLevel*>(lpPktBase);
char szLevel[2];
char szAfterQuery[4096];
_snprintf(szAfterQuery, sizeof(szAfterQuery),
QUERYZ::GetLevel, lpPktUpdateLevel->m_szAccount);
if(CDBAdminTool::GetInstance().ExecuteQuery(szAfterQuery))
{
if(CDBAdminTool::GetInstance().GetData(&szLevel))
{
_snprintf(CDetailLog::m_szBefore, sizeof(CDetailLog::m_szBefore),
"[Tool Admin Level Edit]\r\nAccount: %s\r\nOld Level: %c",
lpPktUpdateLevel->m_szAccount, szLevel[0]);
_snprintf(CDetailLog::m_szAfter, sizeof(CDetailLog::m_szAfter),
"New Level: %c", lpPktUpdateLevel->m_szLevel);
_snprintf(CDetailLog::m_szQuery, CDBAdminTool::MAX_QUERY_LENGTH,
QUERYZ::InsertDetailLog, LogID, TYPE_ADMIN, CDetailLog::m_szBefore, CDetailLog::m_szAfter);
}
}
}
void CDetailLog::PktUpdateIP(LOG_METHOD)
{
PktAdminMgr::PktUpdateIP* lpPktUpdateIP =
static_cast<PktAdminMgr::PktUpdateIP*>(lpPktBase);
char szIP[PktAdminMgr::MAX_IP];
char szBeforeQuery[4096];
_snprintf(szBeforeQuery, sizeof(szBeforeQuery),
QUERYZ::GetIP, lpPktUpdateIP->m_szAccount);
if(CDBAdminTool::GetInstance().ExecuteQuery(szBeforeQuery))
{
if(CDBAdminTool::GetInstance().GetData(&szIP))
{
_snprintf(CDetailLog::m_szBefore, sizeof(CDetailLog::m_szBefore),
"[Tool Admin IP Edit]\r\nAccount: %s\r\nOld IP: %s",
lpPktUpdateIP->m_szAccount, szIP );
_snprintf(CDetailLog::m_szAfter, sizeof(CDetailLog::m_szAfter),
"New IP: %s", lpPktUpdateIP->m_szIP);
_snprintf(CDetailLog::m_szQuery, CDBAdminTool::MAX_QUERY_LENGTH,
QUERYZ::InsertDetailLog, LogID, TYPE_ADMIN, CDetailLog::m_szBefore, CDetailLog::m_szAfter);
}
}
}
void CDetailLog::PktUpdatePasswd(LOG_METHOD)
{
PktAdminMgr::PktUpdatePasswd* lpPktUpdatePasswd = static_cast<PktAdminMgr::PktUpdatePasswd*>(lpPktBase);
char szPassword[PktAdminMgr::MAX_PASSWORD];
char szBeforeQuery[4096];
_snprintf(szBeforeQuery, sizeof(szBeforeQuery), QUERYZ::GetPassword, lpPktUpdatePasswd->m_szAccount);
if(CDBAdminTool::GetInstance().ExecuteQuery(szBeforeQuery))
{
if(CDBAdminTool::GetInstance().GetData(&szPassword))
{
_snprintf(CDetailLog::m_szBefore, sizeof(CDetailLog::m_szBefore),
"[Tool Admin Pass Edit]\r\nAccount: %s\r\nOld Pass: %s",
lpPktUpdatePasswd->m_szAccount, szPassword);
_snprintf(CDetailLog::m_szAfter, sizeof(CDetailLog::m_szAfter),
"New Pass: %s", lpPktUpdatePasswd->m_szPasswd);
_snprintf(CDetailLog::m_szQuery, CDBAdminTool::MAX_QUERY_LENGTH,
QUERYZ::InsertDetailLog, LogID, TYPE_ADMIN, CDetailLog::m_szBefore, CDetailLog::m_szAfter);
}
}
}
void CDetailLog::UpdateDetailLog()
{
if(0 != strlen(CDetailLog::m_szQuery))
{
if(!CDBAdminTool::GetInstance().ExecuteQuery(CDetailLog::m_szQuery))
{
ERRLOG2(g_Log, "운영툴 사용내역 로그를 남기는데 실패했습니다. 쿼리-%s, Err-%s",
CDetailLog::m_szQuery, CDBAdminTool::GetInstance().GetErrorString());
}
ZeroMemory(CDetailLog::m_szQuery, sizeof(CDetailLog::m_szQuery));
ZeroMemory(CDetailLog::m_szBefore, sizeof(CDetailLog::m_szBefore));
ZeroMemory(CDetailLog::m_szAfter, sizeof(CDetailLog::m_szAfter));
}
}

View File

@@ -0,0 +1,48 @@
#ifndef _RYL_DETAILLOG_H_
#define _RYL_DETAILLOG_H_
#include <Network/Protocol/Ryl_AdminMgrProtocol.h>
#define LOG_METHOD PktBase* lpPktBase, unsigned int LogID
struct PktBase;
/*!
\class CDetailLog
운영툴 사용기록 로그 클래스
*/
class CDetailLog
{
enum LOGTYPE
{
TYPE_ADMIN = 1,
TYPE_ITEM,
};
public:
CDetailLog();
~CDetailLog() {}
void (*PktLog[PktAdminMgr::PktCMD::PktEnd]) (LOG_METHOD); // 패킷인덱스 연결 로그 포인터 함수
void UpdateDetailLog(); // 디비에 로그 기록
void InsertLog(unsigned int LogID); // 로그 추가
void SetBefore(char* lpBefore, ...);
void SetAfter (char* lpAfter, ...);
private:
static char m_szBefore[1024];
static char m_szAfter[1024];
static char m_szQuery[5000];
static void PktEmpty (LOG_METHOD) {}
static void PktNewAdmin (LOG_METHOD); // 관리자 계정추가
static void PktDelAdmin (LOG_METHOD); // 관리자 계정삭제
static void PktUpdateLevel (LOG_METHOD); // 관리자 권한 변경
static void PktUpdateIP (LOG_METHOD); // 관리자 접속 IP변경
static void PktUpdatePasswd (LOG_METHOD); // 관리자 패스워드 변경
};
#endif

View File

@@ -0,0 +1,47 @@
#ifndef _RYLAGENTSERVERPARSEDATA_H_
#define _RYLAGENTSERVERPARSEDATA_H_
class CSession;
class CModifyCharacter;
/*!
\class CAgentServerParseData
중계서버에서 받은 캐릭터 정보 파싱
*/
class CAgentServerParseData
{
public:
struct SendInfo
{
unsigned __int64 m_dwSerial;
unsigned long m_dwUID;
unsigned long m_dwCID;
unsigned long m_dwRequestKey;
};
void SetSession(CSession* lpSession) { m_lpSession = lpSession; }
public:
bool PARSE_CHAR_BASIC_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer);
bool PARSE_CHAR_EXTRA_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer);
bool PARSE_CHAR_FRIEND_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer, unsigned short PaseLength);
bool PARSE_CHAR_BAN_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer, unsigned short PaseLength);
bool PARSE_STORE_12_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer);
bool PARSE_STORE_34_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer);
bool UpdateCharacter(CModifyCharacter* lpChar, unsigned __int64 dwSerial,
unsigned long dwUID, unsigned long dwCID, unsigned long dwRequestKey);
bool SEND_CHAR_BASIC_DATA(CModifyCharacter* lpChar, SendInfo& SetData);
bool SEND_CHAR_EXTRA_DATA(CModifyCharacter* lpChar, SendInfo& SetData);
bool SEND_CHAR_FRIEND_DATA(CModifyCharacter* lpChar, SendInfo& SetData);
bool SEND_CHAR_BAN_DATA(CModifyCharacter* lpChar, SendInfo& SetData);
bool SEND_STORE_12_DATA(CModifyCharacter* lpChar, SendInfo& SetData);
bool SEND_STORE_34_DATA(CModifyCharacter* lpChar, SendInfo& SetData);
bool SEND_FINISH_UPDATE_DATA(SendInfo& SetData, unsigned char cOldServerGroupID);
private:
CSession* m_lpSession;
};
#endif

View File

@@ -0,0 +1,118 @@
#include "stdafx.h"
#include "Ryl_AgentServerParseData.h"
#include <Network/Buffer/Ryl_CumulateBuffer.h>
#include <Network/Protocol/Ryl_AdminMgrProtocol.h>
#include <Network/Session/Session.h>
#include <Network/XORCrypt/XORCrypt.h>
#include <Network/Packet/WrapPacket.h>
#include <Network/Packet/PacketStruct/CharLoginOutPacketStruct.h>
#include <Character/ModifyCharacter.h>
#include <Stream/Buffer/Buffer.h>
#include <Stream/Buffer/BufferFactory.h>
#include <Item/ItemFactory.h>
#include <Log/ServerLog.h>
bool CAgentServerParseData::PARSE_CHAR_BASIC_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer)
{
unsigned short* lpSizeArray = reinterpret_cast<unsigned short*>(lpDataBuffer);
char* lpCharDataBuffer = lpDataBuffer + (sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB);
if(!lpCharacter->SetCharacterInfo(lpCharDataBuffer, lpSizeArray))
{
ERRLOG0(g_Log, "PARSE_CHAR_BASIC_DATA 실패");
return false;
}
return true;
}
bool CAgentServerParseData::PARSE_CHAR_EXTRA_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer)
{
CModifyCharacter::CHAR_EXTRA_DATA& ExtraData = lpCharacter->GetExtraData();
ExtraData.m_CharInfoEX = *reinterpret_cast<CHAR_INFOEX*>(lpDataBuffer);
lpDataBuffer += sizeof(CHAR_INFOEX);
ExtraData.m_Quest = *reinterpret_cast<QUEST*>(lpDataBuffer);
lpDataBuffer += sizeof(QUEST);
ExtraData.m_History = *reinterpret_cast<HISTORY*>(lpDataBuffer);
lpDataBuffer += sizeof(HISTORY);
ExtraData.m_Config = *reinterpret_cast<CONFIG*>(lpDataBuffer);
lpDataBuffer += sizeof(CONFIG);
// STORE_INFO
LPSTORE_INFO lpStoreInfo = reinterpret_cast<LPSTORE_INFO>(lpDataBuffer);
Item::CDepositContainer& DepositContainer = lpCharacter->GetDeposit();
DepositContainer.SetPassword(lpStoreInfo->Password, STORE_INFO::MAX_PASS_LEN);
DepositContainer.SetTabFlag(lpStoreInfo->Flag);
DepositContainer.DeductGold(lpCharacter->GetDeposit().GetGold());
DepositContainer.AddGold(lpStoreInfo->Gold);
lpCharacter->RevisionQuestNation();
lpCharacter->ParseQuestData();
return true;
}
bool CAgentServerParseData::PARSE_CHAR_FRIEND_DATA(CModifyCharacter* lpCharacter,
char* lpDataBuffer, unsigned short PaseLength)
{
CFriendList& FriendList = lpCharacter->GetFriendList();
if(!FriendList.SerializeIn(lpDataBuffer, PaseLength))
{
ERRLOG0(g_Log, "PARSE_CHAR_FRIEND_DATA 실패 (친구 리스트 시리얼라이즈 인 실패)");
return false;
}
return true;
}
bool CAgentServerParseData::PARSE_CHAR_BAN_DATA(CModifyCharacter* lpCharacter,
char* lpDataBuffer, unsigned short PaseLength)
{
CBanList& BanList = lpCharacter->GetBanList();
if(!BanList.SerializeIn(lpDataBuffer, PaseLength))
{
ERRLOG0(g_Log, "PARSE_CHAR_BAN_DATA 실패 (거부 리스트 시리얼라이즈 인 실패)");
return false;
}
return true;
}
bool CAgentServerParseData::PARSE_STORE_12_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer)
{
LPSTORE lpStore12 = reinterpret_cast<LPSTORE>(lpDataBuffer);
Item::CDepositContainer& DepositContainer = lpCharacter->GetDeposit();
if(!DepositContainer.SerializeIn(lpStore12->Data, lpStore12->dwSize))
{
ERRLOG0(g_Log, "PARSE_STORE_12_DATA 실패 (창고12 시리얼라이즈 인 실패)");
return false;
}
else
{
lpCharacter->SetOperationFlag(CCharacter::CHAR_INFO_LOADED);
}
return true;
}
bool CAgentServerParseData::PARSE_STORE_34_DATA(CModifyCharacter* lpCharacter, char* lpDataBuffer)
{
LPSTORE lpStore34 = reinterpret_cast<LPSTORE>(lpDataBuffer);
Item::CDepositContainer& DepositContainer = lpCharacter->GetDeposit();
if(!DepositContainer.SerializeIn(lpStore34->Data, lpStore34->dwSize))
{
ERRLOG0(g_Log, "PARSE_STORE_34_DATA 실패 (창고34 시리얼라이즈 인 실패)");
return false;
}
return true;
}

View File

@@ -0,0 +1,349 @@
#include "stdafx.h"
#include "Ryl_AgentServerParseData.h"
#include <Character/ModifyCharacter.h>
#include <Stream/Buffer/Buffer.h>
#include <Stream/Buffer/BufferFactory.h>
#include <Item/ItemFactory.h>
#include <Log/ServerLog.h>
#include <Network/Buffer/Ryl_CumulateBuffer.h>
#include <Network/Protocol/Ryl_AdminMgrProtocol.h>
#include <Network/Session/Session.h>
#include <Network/XORCrypt/XORCrypt.h>
#include <Network/Packet/WrapPacket.h>
#include <Network/Packet/PacketStruct/CharLoginOutPacketStruct.h>
bool CAgentServerParseData::UpdateCharacter(CModifyCharacter* lpChar, unsigned __int64 dwSerial,
unsigned long dwUID, unsigned long dwCID, unsigned long dwRequestKey)
{
SendInfo SetData;
SetData.m_dwSerial = dwSerial;
SetData.m_dwUID = dwUID;
SetData.m_dwCID = dwCID;
SetData.m_dwRequestKey = dwRequestKey;
if (lpChar->m_byChangedInfo & CModifyCharacter::ON_BASIC)
{
SEND_CHAR_BASIC_DATA(lpChar, SetData);
lpChar->OffChangedInfo(CModifyCharacter::OFF_BASIC);
}
if (lpChar->m_byChangedInfo & CModifyCharacter::ON_EXTRA)
{
SEND_CHAR_EXTRA_DATA(lpChar, SetData);
lpChar->OffChangedInfo(CModifyCharacter::OFF_EXTRA);
}
if (lpChar->m_byChangedInfo & CModifyCharacter::ON_FRIEND)
{
SEND_CHAR_FRIEND_DATA(lpChar, SetData);
lpChar->OffChangedInfo(CModifyCharacter::OFF_FRIEND);
}
if (lpChar->m_byChangedInfo & CModifyCharacter::ON_BAN)
{
SEND_CHAR_BAN_DATA(lpChar, SetData);
lpChar->OffChangedInfo(CModifyCharacter::OFF_BAN);
}
if (lpChar->m_byChangedInfo & CModifyCharacter::ON_STROE12)
{
SEND_STORE_12_DATA(lpChar, SetData);
lpChar->OffChangedInfo(CModifyCharacter::OFF_STORE12);
}
if (lpChar->m_byChangedInfo & CModifyCharacter::ON_STORE34)
{
SEND_STORE_34_DATA(lpChar, SetData);
lpChar->OffChangedInfo(CModifyCharacter::OFF_STORE34);
}
if (false == SEND_FINISH_UPDATE_DATA(SetData, lpChar->GetOldServerGroupID()))
{
ERRLOG0(g_Log, "SEND_FINISH_UPDATE_DATA 실패");
return false;
}
return true;
}
bool CAgentServerParseData::SEND_FINISH_UPDATE_DATA(CAgentServerParseData::SendInfo& SetData,
unsigned char cOldServerGroupID)
{
CBuffer* lpBuffer =
CREATE_BUFFER(m_lpSession->GetPolicy().GetBufferFactory(), sizeof(PktAgentServer::PktAdminToolSetData));
PktAgentServer::PktAdminToolSetData* lpPktSetData =
reinterpret_cast<PktAgentServer::PktAdminToolSetData*>(lpBuffer->begin());
lpPktSetData->m_dwSerial = SetData.m_dwSerial;
lpPktSetData->m_dwUID = SetData.m_dwUID;
lpPktSetData->m_dwCID = SetData.m_dwCID;
lpPktSetData->m_dwRequestKey = SetData.m_dwRequestKey;
lpPktSetData->m_cType = PktAgentServer::PktAdminToolSetData::FINISH_UPDATE_DATA;
lpPktSetData->m_cOldServerGroupID = cOldServerGroupID;
PacketWrap::WrapHeader(lpBuffer,
sizeof(PktAgentServer::PktAdminToolSetData), PktAgentServer::PktCMD::CmdAdminToolSetData, 0, 0);
if(!m_lpSession->SendPending(lpBuffer))
{
ERRLOG0(g_Log, "SEND_FINISH_UPDATE_DATA 패킷 전송 실패");
return false;
}
return true;
}
bool CAgentServerParseData::SEND_CHAR_BASIC_DATA(CModifyCharacter* lpChar,
CAgentServerParseData::SendInfo& SetData)
{
unsigned short usBufferSize =
sizeof(PktAgentServer::PktAdminToolSetData) +
sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB + DBUpdateData::MAX_DBUPDATE_SIZE;
CCumulateBuffer cBuffer(usBufferSize + 10, m_lpSession);
char* In_BasicPos = cBuffer.GetBuffer(usBufferSize);
PktAgentServer::PktAdminToolSetData* lpPktSetData =
reinterpret_cast<PktAgentServer::PktAdminToolSetData*>(In_BasicPos);
char* In_DataBuffer = reinterpret_cast<char*>(lpPktSetData + 1);
unsigned short* usSizeArray = reinterpret_cast<unsigned short*>(In_DataBuffer);
int nBufferSize = DBUpdateData::MAX_DBUPDATE_SIZE;
char* In_BasicInfo = static_cast<char*>(In_DataBuffer + sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB);
lpPktSetData->m_dwSerial = SetData.m_dwSerial;
lpPktSetData->m_dwUID = SetData.m_dwUID;
lpPktSetData->m_dwCID = SetData.m_dwCID;
lpPktSetData->m_dwRequestKey = SetData.m_dwRequestKey;
lpPktSetData->m_cType = PktAgentServer::PktAdminToolSetData::CHAR_BASIC_DATA;
lpPktSetData->m_cOldServerGroupID = lpChar->GetOldServerGroupID();
lpChar->GetCharacterInfo(In_BasicInfo, &nBufferSize, usSizeArray);
unsigned int nPktLength = sizeof(PktAgentServer::PktAdminToolSetData) +
sizeof(unsigned short) * DBUpdateData::MAX_UPDATE_DB + nBufferSize;
cBuffer.ResizeLength(nPktLength); // 누적 패킷일때 주의!
PacketWrap::WrapHeader(In_BasicPos, nPktLength, PktAgentServer::PktCMD::CmdAdminToolSetData, 0, 0);
return true;
}
bool CAgentServerParseData::SEND_CHAR_EXTRA_DATA(CModifyCharacter* lpChar,
CAgentServerParseData::SendInfo& SetData)
{
unsigned short usBufferSize = sizeof(CHAR_INFOEX) + sizeof(QUEST) + sizeof(HISTORY) +
sizeof(CONFIG) + sizeof(STORE_INFO) + sizeof(PktAgentServer::PktAdminToolSetData);
CCumulateBuffer cBuffer(usBufferSize, m_lpSession);
char* DataBuffer = cBuffer.GetBuffer(usBufferSize);
PktAgentServer::PktAdminToolSetData* lpPktSetData =
reinterpret_cast<PktAgentServer::PktAdminToolSetData*>(DataBuffer);
char* In_DataBuffer = reinterpret_cast<char*>(lpPktSetData + 1);
CModifyCharacter::CHAR_EXTRA_DATA& ExtraData = lpChar->GetExtraData();
CopyMemory(In_DataBuffer, &ExtraData.m_CharInfoEX, sizeof(CHAR_INFOEX));
In_DataBuffer += sizeof(CHAR_INFOEX);
CopyMemory(In_DataBuffer, &ExtraData.m_Quest, sizeof(QUEST));
In_DataBuffer += sizeof(QUEST);
CopyMemory(In_DataBuffer, &ExtraData.m_History, sizeof(HISTORY));
In_DataBuffer += sizeof(HISTORY);
CopyMemory(In_DataBuffer, &ExtraData.m_Config, sizeof(CONFIG));
In_DataBuffer += sizeof(CONFIG);
lpPktSetData->m_dwSerial = SetData.m_dwSerial;
lpPktSetData->m_dwUID = SetData.m_dwUID;
lpPktSetData->m_dwCID = SetData.m_dwCID;
lpPktSetData->m_dwRequestKey = SetData.m_dwRequestKey;
lpPktSetData->m_cType = PktAgentServer::PktAdminToolSetData::CHAR_EXTRA_DATA;
lpPktSetData->m_cOldServerGroupID = lpChar->GetOldServerGroupID();
LPSTORE_INFO lpStoreInfo = reinterpret_cast<LPSTORE_INFO>(In_DataBuffer);
Item::CDepositContainer& DepositContainer = lpChar->GetDeposit();
memcpy(lpStoreInfo->Password, DepositContainer.GetPassword(), 4);
lpStoreInfo->Password[4] = 0;
lpStoreInfo->Flag = DepositContainer.GetTabFlag();
lpStoreInfo->Gold = DepositContainer.GetGold();
PacketWrap::WrapHeader(DataBuffer, usBufferSize, PktAgentServer::PktCMD::CmdAdminToolSetData, 0, 0);
return true;
}
bool CAgentServerParseData::SEND_CHAR_FRIEND_DATA(CModifyCharacter* lpChar,
CAgentServerParseData::SendInfo& SetData)
{
CFriendList& FriendList = lpChar->GetFriendList();
unsigned short usBufferSize =
sizeof(FriendInfo) * CFriendList::MAX_FRIENDS_NUM + sizeof(PktAgentServer::PktAdminToolSetData);
CCumulateBuffer cBuffer(usBufferSize + 10, m_lpSession);
char* lpDataBuffer = cBuffer.GetBuffer(usBufferSize);
PktAgentServer::PktAdminToolSetData* lpPktSetData =
reinterpret_cast<PktAgentServer::PktAdminToolSetData*>(lpDataBuffer);
char* In_DataBuffer = reinterpret_cast<char*>(lpPktSetData + 1);
lpPktSetData->m_dwSerial = SetData.m_dwSerial;
lpPktSetData->m_dwUID = SetData.m_dwUID;
lpPktSetData->m_dwCID = SetData.m_dwCID;
lpPktSetData->m_dwRequestKey = SetData.m_dwRequestKey;
lpPktSetData->m_cType = PktAgentServer::PktAdminToolSetData::CHAR_FRIEND_DATA;
lpPktSetData->m_cOldServerGroupID = lpChar->GetOldServerGroupID();
unsigned long nBufferSize = sizeof(FriendInfo) * CFriendList::MAX_FRIENDS_NUM;
FriendList.SerializeOut(In_DataBuffer, nBufferSize);
cBuffer.ResizeLength(sizeof(PktAgentServer::PktAdminToolSetData) + nBufferSize);
PacketWrap::WrapHeader(lpDataBuffer,
(sizeof(PktAgentServer::PktAdminToolSetData) + (unsigned short)nBufferSize),
PktAgentServer::PktCMD::CmdAdminToolSetData, 0, 0);
return true;
}
bool CAgentServerParseData::SEND_CHAR_BAN_DATA(CModifyCharacter* lpChar,
CAgentServerParseData::SendInfo& SetData)
{
CBanList& BanList = lpChar->GetBanList();
unsigned short usBufferSize =
sizeof(BanInfo) * CBanList::MAX_BAN_NUM + sizeof(PktAgentServer::PktAdminToolSetData);
CCumulateBuffer cBuffer(usBufferSize + 10, m_lpSession);
char* lpDataBuffer = cBuffer.GetBuffer(usBufferSize);
PktAgentServer::PktAdminToolSetData* lpPktSetData =
reinterpret_cast<PktAgentServer::PktAdminToolSetData*>(lpDataBuffer);
char* In_DataBuffer = reinterpret_cast<char*>(lpPktSetData + 1);
lpPktSetData->m_dwSerial = SetData.m_dwSerial;
lpPktSetData->m_dwUID = SetData.m_dwUID;
lpPktSetData->m_dwCID = SetData.m_dwCID;
lpPktSetData->m_dwRequestKey = SetData.m_dwRequestKey;
lpPktSetData->m_cType = PktAgentServer::PktAdminToolSetData::CHAR_BAN_DATA;
lpPktSetData->m_cOldServerGroupID = lpChar->GetOldServerGroupID();
unsigned long nBufferSize = sizeof(BanInfo) * CBanList::MAX_BAN_NUM;
BanList.SerializeOut(In_DataBuffer, nBufferSize);
cBuffer.ResizeLength(sizeof(PktAgentServer::PktAdminToolSetData) + nBufferSize);
PacketWrap::WrapHeader(lpDataBuffer,
(sizeof(PktAgentServer::PktAdminToolSetData) + (unsigned short)nBufferSize),
PktAgentServer::PktCMD::CmdAdminToolSetData, 0, 0);
return true;
}
bool CAgentServerParseData::SEND_STORE_12_DATA(CModifyCharacter* lpChar, CAgentServerParseData::SendInfo& SetData)
{
unsigned short usBufferSize = sizeof(STORE) + sizeof(PktAgentServer::PktAdminToolSetData);
CCumulateBuffer cBuffer(usBufferSize + 10, m_lpSession);
char* lpDataBuffer = cBuffer.GetBuffer(usBufferSize);
PktAgentServer::PktAdminToolSetData* lpPktSetData =
reinterpret_cast<PktAgentServer::PktAdminToolSetData*>(lpDataBuffer);
char* In_DataBuffer = reinterpret_cast<char*>(lpPktSetData + 1);
Item::CDepositContainer& DepositContainer = lpChar->GetDeposit();
LPSTORE lpStore = reinterpret_cast<LPSTORE>(In_DataBuffer);
const Item::CItemContainer* lpContainer0 = DepositContainer.GetTab(0);
const Item::CItemContainer* lpContainer1 = DepositContainer.GetTab(1);
ZeroMemory(lpDataBuffer, usBufferSize);
lpPktSetData->m_dwSerial = SetData.m_dwSerial;
lpPktSetData->m_dwUID = SetData.m_dwUID;
lpPktSetData->m_dwCID = SetData.m_dwCID;
lpPktSetData->m_dwRequestKey = SetData.m_dwRequestKey;
lpPktSetData->m_cType = PktAgentServer::PktAdminToolSetData::STORE_12_DATA;
lpPktSetData->m_cOldServerGroupID = lpChar->GetOldServerGroupID();
if (NULL != lpContainer0 && NULL != lpContainer1)
{
lpStore->dwSize = STORE::MAX_STORE_SIZE;
if (lpContainer0->SerializeOut(lpStore->Data, lpStore->dwSize))
{
unsigned long dwContainer0Size = lpStore->dwSize;
lpStore->dwSize = STORE::MAX_STORE_SIZE - dwContainer0Size;
if (lpContainer1->SerializeOut(lpStore->Data + dwContainer0Size, lpStore->dwSize))
{
lpStore->dwSize += dwContainer0Size;
cBuffer.ResizeLength(usBufferSize);
PacketWrap::WrapHeader(lpDataBuffer,
usBufferSize, PktAgentServer::PktCMD::CmdAdminToolSetData, 0, 0);
return true;
}
}
}
cBuffer.ResizeLength(0);
return false;
}
bool CAgentServerParseData::SEND_STORE_34_DATA(CModifyCharacter* lpChar,
CAgentServerParseData::SendInfo& SetData)
{
unsigned short usBufferSize = sizeof(STORE) + sizeof(PktAgentServer::PktAdminToolSetData);
CCumulateBuffer cBuffer(usBufferSize + 10, m_lpSession);
char* lpDataBuffer = cBuffer.GetBuffer(usBufferSize);
PktAgentServer::PktAdminToolSetData* lpPktSetData =
reinterpret_cast<PktAgentServer::PktAdminToolSetData*>(lpDataBuffer);
char* In_DataBuffer = reinterpret_cast<char*>(lpPktSetData + 1);
Item::CDepositContainer& DepositContainer = lpChar->GetDeposit();
LPSTORE lpStore = reinterpret_cast<LPSTORE>(In_DataBuffer);
const Item::CItemContainer* lpContainer0 = DepositContainer.GetTab(2);
const Item::CItemContainer* lpContainer1 = DepositContainer.GetTab(3);
ZeroMemory(lpDataBuffer, usBufferSize);
lpPktSetData->m_dwSerial = SetData.m_dwSerial;
lpPktSetData->m_dwUID = SetData.m_dwUID;
lpPktSetData->m_dwCID = SetData.m_dwCID;
lpPktSetData->m_dwRequestKey = SetData.m_dwRequestKey;
lpPktSetData->m_cType = PktAgentServer::PktAdminToolSetData::STORE_34_DATA;
lpPktSetData->m_cOldServerGroupID = lpChar->GetOldServerGroupID();
if (NULL != lpContainer0 && NULL != lpContainer1)
{
lpStore->dwSize = STORE::MAX_STORE_SIZE;
if (lpContainer0->SerializeOut(lpStore->Data, lpStore->dwSize))
{
unsigned long dwContainer0Size = lpStore->dwSize;
lpStore->dwSize = STORE::MAX_STORE_SIZE - dwContainer0Size;
if (lpContainer1->SerializeOut(lpStore->Data + dwContainer0Size, lpStore->dwSize))
{
lpStore->dwSize += dwContainer0Size;
cBuffer.ResizeLength(usBufferSize);
PacketWrap::WrapHeader(lpDataBuffer,
usBufferSize, PktAgentServer::PktCMD::CmdAdminToolSetData, 0, 0);
return true;
}
}
}
cBuffer.ResizeLength(0);
return false;
}

View File

@@ -0,0 +1,70 @@
#include "stdafx.h"
#include < Stream/Buffer/Buffer.h >
#include < Stream/Buffer/BufferFactory.h >
#include < Network/Session/Session.h >
#include < Network/Buffer/Ryl_CumulateBuffer.h >
//사용용도는 Loop나 연속적으로 패킷을 보낼상항이 생겼을경우 일단 이놈한테 누적시키고 보내버리자....
CCumulateBuffer::CCumulateBuffer(unsigned long BufferLength, CSession* pSession)
{
m_lpBuffer = new char[BufferLength];
m_lpSession = pSession;
m_lpNowPos = m_lpBuffer;
m_lpEndPos = m_lpBuffer + BufferLength;
m_BufferLength = BufferLength;
m_FillLength = 0;
}
CCumulateBuffer::~CCumulateBuffer( )
{
if(m_FillLength) SendAll();
if(m_lpBuffer)
{
delete [] m_lpBuffer;
}
}
char* CCumulateBuffer::GetBuffer(unsigned int Length)
{
if((m_lpNowPos + Length) > m_lpEndPos)
{
//버퍼에 더이상 들어갈 공간이 없다 버퍼의 내용을 전부 비우자.
//버퍼에 누적된 패킷을 전부 보내버리잣..
if(!SendAll())
{
return NULL;
}
}
char* PktPos = m_lpNowPos;
m_lpNowPos += Length; // 다음 패킷이 누적될 포인터
m_FillLength += Length; // 현재 버퍼 사용량
return PktPos; // 누적될 지점
}
//PktBase를 상속받은 패킷을 꼭~ WrapHeader을 해줘야한다 안하면 싼다..
bool CCumulateBuffer::SendAll()
{
CBuffer* SendBuffer = CREATE_BUFFER(m_lpSession->GetPolicy().GetBufferFactory(), m_FillLength);
if((SendBuffer == NULL) || (m_lpSession == NULL))
{
return false;
}
SendBuffer->push(m_lpBuffer, m_FillLength);
m_lpNowPos = m_lpBuffer;
m_FillLength = 0;
return m_lpSession->SendPending(SendBuffer);
}

View File

@@ -0,0 +1,33 @@
#ifndef _CUMULATE_BUFFER_H_
#define _CUMULATE_BUFFER_H_
class CBuffer;
class CSession;
// 패킷 누적버퍼
class CCumulateBuffer
{
public:
CCumulateBuffer(unsigned long BufferLength, CSession* pSession);
~CCumulateBuffer();
char* GetBuffer(unsigned int Length); // 할당된 버퍼 얻기
bool SendAll(); // 현재 버퍼에 있는 내용을 전부 보내기
// 사용중인 버퍼길이 강제 조정
void ResizeLength(unsigned int FillLength) { m_FillLength = FillLength; }
private:
char* m_lpBuffer;
char* m_lpNowPos;
char* m_lpEndPos;
CSession* m_lpSession;
unsigned int m_FillLength;
unsigned int m_BufferLength;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
#include "stdafx.h"
#include "ServerInfo.h"
//#include "string.h"
const char* CServerInfo::ms_szInfoFileName = "AdminToolServerSetup.ini";
CServerInfo::CServerInfo()
{
Reload(ms_szInfoFileName);
}
CServerInfo::~CServerInfo()
{
m_ServerInfoTable.clear( );
}
const char* CServerInfo::GetFileName( )
{
return CServerInfo::ms_szInfoFileName;
}
bool CServerInfo::Reload(const char* szFileName)
{
m_ServerInfoTable.clear();
FILE* lpFile = fopen(szFileName, "rt");
if(NULL == lpFile)
{
return false;
}
const int MAX_LINE = 4096;
char szBuffer[MAX_LINE];
std::string szKeyString;
while(0 != fgets(szBuffer, MAX_LINE, lpFile))
{
char* szKey = strtok(szBuffer, " =\t\n");
char* szValue = strtok(NULL, " =\t\n");
if(NULL != szKey && NULL != szValue && '[' != szKey[0] && '#' != szKey[0])
{
szKeyString.assign(szKey);
m_ServerInfoTable[szKeyString] = szValue;
}
}
fclose(lpFile);
return true;
}
const char* CServerInfo::GetValue(const char* szKeyName)
{
const int MAX_BUFFER = 256;
char szBuffer[MAX_BUFFER];
strncpy(szBuffer, szKeyName, MAX_BUFFER);
szBuffer[MAX_BUFFER - 1] = 0;
ServerInfoTable::iterator finditr = m_ServerInfoTable.find(szBuffer);
return (finditr != m_ServerInfoTable.end()) ? finditr->second.c_str() : NULL;
}

View File

@@ -0,0 +1,25 @@
#ifndef _SERVER_INFO_H_
#define _SERVER_INFO_H_
#include <Pattern/Singleton.h>
// ½ºÅ©¸³Æ® ÆÄÀÏ ( Key = Value )
class CServerInfo : public CStaticSingleton<CServerInfo>
{
public:
CServerInfo();
~CServerInfo();
bool Reload(const char* szFileName = ms_szInfoFileName);
const char* GetValue(const char* szKeyName);
const char* GetFileName();
private:
typedef std::map<std::string, std::string> ServerInfoTable;
ServerInfoTable m_ServerInfoTable;
static const char* ms_szInfoFileName;
};
#endif

View File

@@ -0,0 +1,8 @@
// stdafx.cpp : 표준 포함 파일만 들어 있는 소스 파일입니다.
// RylToolLibrary.pch는 미리 컴파일된 헤더가 됩니다.
// stdafx.obj에는 미리 컴파일된 형식 정보가 포함됩니다.
#include "stdafx.h"
// TODO: 필요한 추가 헤더는
// 이 파일이 아닌 STDAFX.H에서 참조합니다.

View File

@@ -0,0 +1,101 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#pragma warning(disable:4800)
// 각종 점검용 정의들. 사용하지 않을 경우는 (void*)0 로 대신할 것.
#ifdef _DEBUG
#define PERFORMANCE_CHECK(x) x
#else
#define PERFORMANCE_CHECK(x) x
#endif
#ifdef _DEBUG
#define DEBUG_CRT_MEMORY(x) x
#else
#define DEBUG_CRT_MEMORY(x) (void*)0
#endif
// Windows Header Files:
// MFC 사용시에는 인클루드 하면 안됨;
// #include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
/*
// TODO: reference additional headers your program requires here
// MFC의 공통 부분과 무시 가능한 경고 메시지에 대한 숨기기를 해제합니다.
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC 핵심 및 표준 구성 요소
#include <afxext.h> // MFC 익스텐션
#include <afxdisp.h> // MFC 자동화 클래스
#include <afxdtctl.h> // Internet Explorer 4 공용 컨트롤에 대한 MFC 지원
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // Windows 공용 컨트롤에 대한 MFC 지원
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxdlgs.h>
*/
// 소켓 관련 헤더들
#include <winsock2.h>
#include <mswsock.h>
#include <iphlpapi.h> // for IP Help functions, that gets local IP address
#include <ws2tcpip.h> // tcp/ip specific options
#include <wsipx.h> // for IPX/SPX
#include <wsnwlink.h>
// DB관련 헤더들
#include <msdasc.h> // OLE DB Service Component header
#include <msdaguid.h> // OLE DB Root Enumerator
#include <msdasql.h> // MSDASQL - Default provider
#include <sqloledb.h> // MS SQL
// 기본 헤더들
#include <windows.h>
#include <process.h>
#include <shellapi.h>
#include <tchar.h>
// C 함수 헤더들
#include <cassert>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdarg>
#include <cstddef>
#include <cstdlib>
// STL 헤더들
#include <new>
#include <set>
#include <map>
#include <hash_map>
#include <vector>
#include <list>
#include <string>
#include <limits>
#include <bitset>
#include <complex>
#include <algorithm>
#include <numeric>
#include <utility>
#include <functional>