Files
2022-10-26 12:25:11 +08:00

487 lines
17 KiB
C++

#include "stdafx.h"
#include "VersionControl.h"
#include "Define.h"
#include <SCSlotStruct.h>
#include <SCItemSlot.h>
#include <ItemInfoParser.h>
#include "QuestDefine.h"
namespace nsSlot {
;
// (NOTE) (f100713.1L) this function has rules for the version content.
// the inputed item stream should be the latest version of an item specification
static bool ContainerItemConvertByContent(DURATYPE used_slot_num, ITEMSTREAMEX* to_stream_array INOUT)
{
ItemInfoParser* const item_parser = ItemInfoParser::Instance();
ITEMSTREAMEX* it = to_stream_array;
ITEMSTREAMEX* const end = to_stream_array + used_slot_num;
for (; it != end; ++it)
{
const SLOTCODE item_code = it->Part.wCode;
// (CHANGES) (f100802.2L) remove data regard as planner's intend
// if can't find item in item scripts
const BASE_ITEMINFO* item_info = (item_code == 0)
? NULL
: item_parser->GetItemInfo(item_code);
if (item_info == NULL) {
ZeroMemory(it, sizeof(*it));
continue;
}
#if defined(_GLOBAL) || defined(_RUSSIA)
switch (item_code)
{ // convert the item code to solve too hard script versioning in the Global version
//case 47005: // mega-mistone for event
case 47060: // mega-mistone
it->Part.wCode = 4204; // common mega-mistone
break;
}
#endif
}
return true;
}
// (CHANGES) (f100806.1L) change to a no-template version
static bool
ContainerItemConvert(SLOTIDX slot_index, const POSTYPE used_slot_num,
const int from_version IN, BYTE* const from_stream_array IN,
const int from_stream_node_size, //sizeof(ITEMSTREAMEX_VER1,2,...)
int& to_version OUT, ITEMSTREAMEX* const to_stream_array OUT)
{
const int kLatestVersion = ITEM_STREAM_SIZE_LAST_VERSION;
static const int kNumberOfMaxSlotsArray[SI_MAX] =
{
0, //SI_TEMPINVENTORY = 0,
MAX_INVENTORY_SLOT_NUM, //SI_INVENTORY,
MAX_EQUIPMENT_SLOT_NUM, //SI_EQUIPMENT,
MAX_WAREHOUSE_SLOT_NUM, //SI_WAREHOUSE,
0, //SI_SKILL, not item stream
0, //SI_QUICK, not item stream
0, //SI_STYLE, not item stream
MAX_GUILD_WAREHOUSE_SLOT_NUM, //SI_GUILDWAREHOUSE,
};
BOOST_STATIC_ASSERT(MAX_INVENTORY_TAB_TOTAL_NUM * MAX_INVENTORY_SLOT_PER_TAB ==
MAX_INVENTORY_SLOT_NUM);
//
if (slot_index >= _countof(kNumberOfMaxSlotsArray)) {
ASSERT(!"Unexpected status: slot index out of ranges");
return false;
}
//
const int number_of_max_slots = kNumberOfMaxSlotsArray[slot_index];
if (number_of_max_slots == 0) {
ASSERT(!"Unexpected status: a stream type of a slot index is not an item stream");
return false;
}
if (number_of_max_slots < used_slot_num) {
assert(number_of_max_slots >= used_slot_num);
__debugbreak();
return false;
}
// ITEMSTREAMEX
const int used_size = sizeof(*to_stream_array) * used_slot_num;
/*
int number_of_max_slots = 0;
int used_size = used_slot_num * sizeof(ITEMSTREAMEX);
switch (slot_index)
{
case SI_INVENTORY:
number_of_max_slots = MAX_INVENTORY_TAB_TOTAL_NUM * MAX_INVENTORY_SLOT_PER_TAB;
break;
case SI_EQUIPMENT:
number_of_max_slots = MAX_EQUIPMENT_SLOT_NUM;
break;
case SI_TEMPINVENTORY:
number_of_max_slots = MAX_TEMPINVENTORY_SLOT_NUM;
break;
case SI_WAREHOUSE:
number_of_max_slots = MAX_WAREHOUSE_SLOT_NUM;
break;
case SI_GUILDWAREHOUSE:
number_of_max_slots = MAX_GUILD_WAREHOUSE_SLOT_NUM;
break;
default:
ASSERT(false);
return false;
break;
}
*/
// 사용중인 슬롯의 버전변환
if (from_version == kLatestVersion)
{
CopyMemory(to_stream_array, from_stream_array, used_size);
}
else
{
// (CHANGES) (f100806.1L)
BYTE* from_offset = from_stream_array;
for (int i = 0; i < used_slot_num; ++i, (from_offset += from_stream_node_size))
{
SCItemSlot::ConvertStream(from_version, from_offset, to_version, &to_stream_array[i]);
//SCItemSlot::ConvertStream(from_version, (BYTE*)&from_stream_array[i],
// to_version, &to_stream_array[i]);
if (to_version != kLatestVersion)
{
to_version = -1;
return false;
}
}
}
// (CHANGES) (f100805.1L) clear an unused range
;{
size_t clear_size = static_cast<size_t>(\
reinterpret_cast<char*>(&to_stream_array[number_of_max_slots]) -
reinterpret_cast<char*>(&to_stream_array[used_slot_num]));
if (clear_size) {
ZeroMemory(&to_stream_array[used_slot_num], clear_size);
}
#if SUN_CODE_BACKUP
// 사용하지 않는 슬롯(캐쉬슬롯)의 초기화
int init_size = (number_of_max_slots - used_slot_num) * sizeof(ITEMSTREAMEX);
ZeroMemory((((BYTE*)to_stream_array) + used_size), init_size);
#endif
};
;{
// (CHANGES) (f100805.5L) change process order
// (NOTE) (f100713.1L) this function has rules for the version content.
nsSlot::ContainerItemConvertByContent(used_slot_num, to_stream_array);
};
// last operation
to_version = kLatestVersion;
//
return true;
}
static int GetFromVersionUsedSlotNum(SLOTIDX slot_index, int from_version, int used_slot_num)
{
int used_slot_num_from_version = used_slot_num;
if (slot_index != SI_EQUIPMENT) {
return used_slot_num_from_version;
}
switch (from_version)
{
case ITEM_STREAM_SIZE_LAST_VERSION:
used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM;
break;
//#ifdef _NA000109_100427_SOLAR_SLOT_UPDATE_TO_VER8_
// case x: used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM_Vx; break;
//#endif
#ifdef _NA002237_100802_EP2_SOCKET_SYSTEM_DB_
case 7: used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM_V7; break; // 1004
#endif
case 6: used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM_V6; break; // 905
case 5: used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM_V5; break; // 904
case 4: used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM_V4; break;
case 3: used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM_V3; break;
case 2: used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM_V2; break;
case 1: used_slot_num_from_version = MAX_EQUIPMENT_SLOT_NUM_V1; break;
}
return used_slot_num_from_version;
}
// (CHANGES) change a ContainerItemConvert to a no-template version
static const uint8_t kItemStreamSizeArray[ITEM_STREAM_SIZE_LAST_VERSION + 1] =
{
0, // version 0 - not used, unexpected status
sizeof(ITEMSTREAMEX_VER1),
sizeof(ITEMSTREAMEX_VER2),
sizeof(ITEMSTREAMEX_VER3),
sizeof(ITEMSTREAMEX_VER4),
sizeof(ITEMSTREAMEX_VER5),
sizeof(ITEMSTREAMEX_VER6),
#ifdef _NA002237_100802_EP2_SOCKET_SYSTEM_DB_
sizeof(ITEMSTREAMEX_VER7),
#endif
//
sizeof(ITEMSTREAMEX) // end of record
};
}; //end of namespace 'nsSlot'
//==================================================================================================
//==================================================================================================
//==================================================================================================
bool VersionControl::ConvertItem(int* converted_version, void* converted_stream,
const int from_version, const void* from_stream)
{
if (from_version == 0 || from_version >= _countof(nsSlot::kItemStreamSizeArray)) {
ASSERT(!"Unexpected version");
return false;
};
const int kLatestVersion = ITEM_STREAM_SIZE_LAST_VERSION;
BOOST_STATIC_ASSERT(kLatestVersion + 1 == _countof(nsSlot::kItemStreamSizeArray));
ITEMSTREAMEX* result_stream = reinterpret_cast<ITEMSTREAMEX*>(converted_stream);
if (from_version == kLatestVersion)
{
*converted_version = from_version;
CopyMemory(result_stream, from_stream, sizeof(*result_stream));
return true;
}
else
{
int result_version = 0;
uint8_t* from_stream_it = reinterpret_cast<uint8_t*>(const_cast<void*>(from_stream));
SCItemSlot::ConvertStream(from_version, from_stream_it, result_version, result_stream);
if (result_version != kLatestVersion)
{
*converted_version = -1;
return false;
}
//
*converted_version = result_version;
}
// (CHANGES) (f100805.5L) change process order
// (NOTE) (f100713.1L) this function has rules for the version content.
nsSlot::ContainerItemConvertByContent(1, result_stream);
//assert 'result_stream == converted_stream'
//
return true;
}
BOOL VersionControl::ItemConverter(SLOTIDX slot_index, int used_slot_num IN,
int from_version IN, BYTE* from_stream IN,
int& to_version OUT, BYTE* to_stream OUT)
{
// NOTE: latest_version == ITEM_STREAM_SIZE_LAST_VERSION
if (used_slot_num < 0) {
return false;
}
//
const int used_slot_num_from_version = \
nsSlot::GetFromVersionUsedSlotNum(slot_index, from_version, used_slot_num);
//
if (from_version == 0 || from_version >= _countof(nsSlot::kItemStreamSizeArray)) {
ASSERT(!"Unexpected version");
return false;
};
//
const int from_stream_node_size = nsSlot::kItemStreamSizeArray[from_version];
bool success = nsSlot::ContainerItemConvert(\
slot_index, used_slot_num_from_version,
from_version, from_stream, from_stream_node_size,
to_version, reinterpret_cast<ITEMSTREAMEX*>(to_stream));
//
return success;
/*
switch (from_version)
{
case ITEM_STREAM_SIZE_LAST_VERSION:
if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
from_version, (ITEMSTREAMEX*)from_stream,
to_version, (ITEMSTREAMEX*)to_stream))
{
return false;
}
break;
//#ifdef _NA000109_100427_SOLAR_SLOT_UPDATE_TO_VER8_
// case x:
// if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
// from_version, reinterpret_cast<ITEMSTREAMEX_VER7*>(from_stream),
// to_version, reinterpret_cast<ITEMSTREAMEXx*>(to_stream)))
// {
// return false;
// }
// break;
//#endif
#ifdef _NA002237_100802_EP2_SOCKET_SYSTEM_DB_
case 7:
if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
from_version, (ITEMSTREAMEX_VER7*)from_stream,
to_version, (ITEMSTREAMEX*)to_stream))
{
return false;
}
break;
#endif
// convert to v7 from v6
case 6:
if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
from_version, (ITEMSTREAMEX_VER6*)from_stream,
to_version, (ITEMSTREAMEX*)to_stream))
{
return false;
}
break;
case 5:
if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
from_version, (ITEMSTREAMEX_VER5*)from_stream,
to_version, (ITEMSTREAMEX*)to_stream))
{
return false;
}
break;
case 4:
if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
from_version, (ITEMSTREAMEX_VER4*)from_stream,
to_version, (ITEMSTREAMEX*)to_stream))
{
return false;
}
break;
case 3:
if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
from_version, (ITEMSTREAMEX_VER3*)from_stream,
to_version, (ITEMSTREAMEX*)to_stream))
{
return false;
}
break;
case 2:
if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
from_version, (ITEMSTREAMEX_VER2*)from_stream,
to_version, (ITEMSTREAMEX*)to_stream))
{
return false;
}
break;
case 1:
if (!ContainerItemConvert(slot_index, used_slot_num_from_version,
from_version, (ITEMSTREAMEX_VER1*)from_stream,
to_version, (ITEMSTREAMEX*)to_stream))
{
return false;
}
break;
default:
ASSERT(false);
return false;
}
return true;
*/
}
//{__NA_001337_20090511_EXPANSION_QUEST_COMPL_NUM
BOOL VersionControl::QuestConverter( OUT int& iDstVersion, OUT BYTE* pDstStreamProgr, OUT BYTE* pDstStreamCompl,
const int iSrcVersion, const BYTE* pSrcStreamProgr, const BYTE* pSrcStreamCompl )
{
switch( iSrcVersion )
{
//////////////////////////////////////////////////////////////////////////
// 가장 최신 버전. (현재:2)
case QUESTPART_PROGR::QUESTPART_PROGR_VERSION:
memcpy( pDstStreamProgr, pSrcStreamProgr, MAX_PROGR_QUESTSTREAM_SIZE );
memcpy( pDstStreamCompl, pSrcStreamCompl, QUESTPART_COMPL::MAX_QUEST_COMPL_NUM );
iDstVersion = QUESTPART_PROGR::QUESTPART_PROGR_VERSION;
return TRUE;
//////////////////////////////////////////////////////////////////////////
//
case QUESTPART_PROGR_V1::QUESTPART_PROGR_VERSION:
if( !_QuestProgrConvert( (QUESTPART_PROGR_V2*)pDstStreamProgr, (QUESTPART_PROGR_V1*)pSrcStreamProgr) )
return FALSE;
if( !_QuestComplConvert( (QUESTPART_COMPL_V2*)pDstStreamCompl, (QUESTPART_COMPL_V1*)pSrcStreamCompl) )
return FALSE;
iDstVersion = QUESTPART_PROGR_V2::QUESTPART_PROGR_VERSION;
break;
//////////////////////////////////////////////////////////////////////////
//
case QUESTPART_PROGR_V0::QUESTPART_PROGR_VERSION:
if( !_QuestProgrConvert( (QUESTPART_PROGR_V1*)pDstStreamProgr, (QUESTPART_PROGR_V0*)pSrcStreamProgr) )
return FALSE;
if( !_QuestComplConvert( (QUESTPART_COMPL_V1*)pDstStreamCompl, (QUESTPART_COMPL_V0*)pSrcStreamCompl) )
return FALSE;
iDstVersion = QUESTPART_PROGR_V1::QUESTPART_PROGR_VERSION;
break;
//////////////////////////////////////////////////////////////////////////
//
default:
ASSERT(FALSE);
return FALSE;
}
//////////////////////////////////////////////////////////////////////////
//
//오랜만에 들어온 유저의 경우 한단계씩 버전업 한다.
if( QUESTPART_PROGR::QUESTPART_PROGR_VERSION != iDstVersion )
{
static BYTE _SrcStreamProgr[MAX_PROGR_QUESTSTREAM_SIZE] = {0,};
static BYTE _SrcStreamCompl[MAX_COMPL_QUESTSTREAM_SIZE] = {0,};
memcpy( _SrcStreamProgr, pDstStreamProgr, MAX_PROGR_QUESTSTREAM_SIZE );
memcpy( _SrcStreamCompl, pDstStreamCompl, MAX_COMPL_QUESTSTREAM_SIZE );
QuestConverter( iDstVersion, pDstStreamProgr, pDstStreamCompl,
iDstVersion, _SrcStreamProgr, _SrcStreamCompl);
}
return TRUE;
}
// DB에 직접적인 변화는 없으나, 구조체 변화에 따라 버전 변경한다.
// 완료 스트림도 버전값을 같이 사용함으로 버전 변경한다.
BOOL VersionControl::_QuestProgrConvert( OUT QUESTPART_PROGR_V2* pDstStreamProgr, const QUESTPART_PROGR_V1* pSrcStreamProgr )
{
for( int i = 0; i < QUESTPART_PROGR_V1::MAX_QUEST_PROGR_NUM; ++i)
pDstStreamProgr[i] = pSrcStreamProgr[i];
return TRUE;
}
BOOL VersionControl::_QuestComplConvert( OUT QUESTPART_COMPL_V2* pDstStreamCompl, const QUESTPART_COMPL_V1* pSrcStreamCompl )
{
memcpy( pDstStreamCompl, pSrcStreamCompl, QUESTPART_COMPL_V1::MAX_QUEST_COMPL_NUM );
return TRUE;
}
// 사용되지 않는 퀘스트 대역 초기화
// 1번과 2번의 경우 기존 DB에서 케릭생성시 추가되는 퀘스트이나 현재 사용하지 않으므로 초기화 한다.
// 이후 필요시 여기에서 초기화 하지 않는 대역의 퀘스트를 사용하여야한다.(1500번 이후가 안전)
BOOL VersionControl::_QuestProgrConvert( OUT QUESTPART_PROGR_V1* pDstStreamProgr, const QUESTPART_PROGR_V0* pSrcStreamProgr )
{
for( int i = 0; i < QUESTPART_PROGR_V0::MAX_QUEST_PROGR_NUM; ++i)
{
const QCODE QCode = pSrcStreamProgr[i].m_QCode;
if( Between<QCODE>(QCode, 1, 92) ||
Between<QCODE>(QCode, 800, 930) ||
Between<QCODE>(QCode, 935, 986) ||
Between<QCODE>(QCode, 1014, 1099) ||
Between<QCODE>(QCode, 1200, 1219) )
{
pDstStreamProgr[i].init();
}
else
pDstStreamProgr[i] = pSrcStreamProgr[i];
}
return TRUE;
}
BOOL VersionControl::_QuestComplConvert( OUT QUESTPART_COMPL_V1* pDstStreamCompl, const QUESTPART_COMPL_V0* pSrcStreamCompl )
{
// 0~1499번(1500) 까지의 기록은 일단 저장한다.
memcpy( pDstStreamCompl, pSrcStreamCompl, QUESTPART_COMPL_V0::MAX_QUEST_COMPL_NUM );
// 1500~ 3000(1501) 은 초기화
ZeroMemory( &pDstStreamCompl[QUESTPART_COMPL_V0::MAX_QUEST_COMPL_NUM],
QUESTPART_COMPL_V1::MAX_QUEST_COMPL_NUM-QUESTPART_COMPL_V0::MAX_QUEST_COMPL_NUM );
//사용되지 않는 퀘스트 대역 초기화
ZeroMemory( &pDstStreamCompl[1], 93 );
ZeroMemory( &pDstStreamCompl[800], 131 );
ZeroMemory( &pDstStreamCompl[935], 52 );
ZeroMemory( &pDstStreamCompl[1014], 86 );
ZeroMemory( &pDstStreamCompl[1200], 20 );
return TRUE;
}
//}__NA_001337_20090511_EXPANSION_QUEST_COMPL_NUM