November Source Bug/ Dupe Fix Release
#1

2Here is all known fixes that i have for dupes. and other additional fixes. If you have any other fixes and chose to share them it would be appreciated. 

 I do apologize ahead of time for anyone this may upset by releasing these fixes. 

I think everyone in lc likes to keep all these fixes private  and by doing this anyone who wants to create a server can't really.

credits: rrkbmz,reza (whoever else i missed)



these fixes are from 1 (source i paid for and 2 reza's source leak)



1.mysterious statue dupe (negative gold value)

Server/GameServer/doFuncExpressSystem.cpp


after void process_use_unsearchable_stonestatue(CPC* ch, CNetMsg::SP& msg)

put this :

//change this:
if (sendItem->Count() < packet->itemCount)

//to this:
if (sendItem->Count() < packet->itemCount || packet->itemCount <= 0)



2. drop item dupe (negative value)

Server/GameServer/DoFuncItem.cpp

after void do_ItemThrow(CPC* ch, CNetMsg::SP& msg)



put this:

 

// you will see somthing like this in your code.
ArtifactManager::instance()->item_drop(item);
}

CItem* dropitem = NULL;

// new code will look like this:

ArtifactManager::instance()->item_drop(item);
}

if (packet->count <= 0) {
CNetMsg::SP rmsg(new CNetMsg);
SysMsg(rmsg, MSG_SYS_FULL_INVENTORY);
SEND_Q(rmsg, ch->m_desc);
return;
}
CItem* dropitem = NULL;



3. guild storage dupe



this is a little to big to write in a couple lines ill just link the fixes:

gameserver/pc.cpp

gameserver/ProcHelperMsg.cpp

gameserver/Character.h

gameserver/DoFuncGuild.cpp


2

2

2

2

 

 

 

here is an example of what you're looking for :

2

2

2

2

4. double login dupe (here their might be more then 1 fix for this method might not full fix it) 

 Server/GameServer/Descriptor.cpp


in void CDescriptor::operate( rnSocketIOService* service )

put this:

 

// you'll see this code (just search it)
packet->subType = MSG_RETURN_TO_SELECT_CHANNEL;
rmsg->setSize(sizeof(pTypeBase));
SEND_Q(rmsg, this);
}
break;
default:

//replace that code with this:
packet->subType = MSG_RETURN_TO_SELECT_CHANNEL;
rmsg->setSize(sizeof(pTypeBase));
SEND_Q(rmsg, this);
this->Close("");
return;
}
break;
default:

//next you'll see this
LOG_ERROR("Invalid packet. type[%d] / now is character select screen. user_index",
msg->m_mtype, this->m_index);
this->Close("Invalid packet. now is character select screen");
return;
}
break;

//replace it with this

LOG_ERROR("Invalid packet. type[%d] / now is character select screen. user_index",
msg->m_mtype, this->m_index);
//this->Close("Invalid packet. now is character select screen");
GAMELOG << init("INVALID_PACKET")
<< "user_index" << delim
<< this->m_index << delim
<< end;
return;
}
break;





5. Quest Exploit (dupe)

Server/GameServer/DoFuncQuest.cpp


after void do_Quest(CPC* ch, CNetMsg::SP& msg)



put this:

// you'll see this
case MSG_QUEST_RESTORE_ABANDON:
do_QuestRestoreAbandon(ch, msg); // 포기 퀘스트 복구
break;
case MSG_QUEST_ITEM_REQ:
do_QuestItemReq(ch, msg); // 완료한 퀘스트중 퀘스트 아이템 받기
break;

//change it to this
case MSG_QUEST_RESTORE_ABANDON:
do_QuestRestoreAbandon(ch, msg); // 포기 퀘스트 복구
break;

Next we'll want to disable the function too 

after void do_QuestRestoreAbandon(CPC* ch, CNetMsg::SP& msg)|



put this:

 

//the deefault code
void do_QuestItemReq(CPC* ch, CNetMsg::SP& msg)

//disable this whole function or delete it

// this disables


6. Gold Dupe

Server/GameServer/DoFuncEtc.cpp

put this:

 

//search for this MSG_MANAGEMENT_STATE_CHANGE
if(ch->m_inventory.getMoney() < needMoney)
{
// ERROR 돈 없음
CNetMsg::SP rmsg(new CNetMsg);
DVDManagementMsg( rmsg, MSG_MANAGEMENT_ENV_CHANGE );
RefMsg(rmsg) << (unsigned char) MSG_DVD_ERROR_MONEY;
SEND_Q( rmsg, ch->m_desc );
return;
}
else
//modify this
if(ch->m_inventory.getMoney() < needMoney)

//to this
if( ch->m_inventory.getMoney() < needMoney || needMoney <= 0)

//next in case MSG_MANAGEMENT_ENV_CHANGE :
//find this
if( ch->m_inventory.getMoney() < needMoney)
{
// ERROR �� ����
CNetMsg::SP rmsg(new CNetMsg);
DVDManagementMsg( rmsg, MSG_MANAGEMENT_ENV_CHANGE );
RefMsg(rmsg) << (unsigned char) MSG_DVD_ERROR_MONEY;
SEND_Q( rmsg, ch->m_desc );
return;
}
else
//change it to this
if( ch->m_inventory.getMoney() < needMoney || needMoney <=0)





Additionally here are some secondary crash fixes:



Area.cpp:

 

//after this
for (; it != endit; ++it)
{
CNPCRegenInfo* p = *(it);
p->m_lastDieTime = gserver->m_pulse + GetRandom(1, p->m_regenSec / 2);
p->m_bAlive = false;
}

//add this
if (this->m_RaidDifficulty > 2 || this->m_RaidDifficulty <= -1)
{
this->m_RaidDifficulty = 0;
}



Raidata.cpp:

2



DoFuncExpedtion.cpp:

// in this function
void do_ExpedChangeTypeReq(CPC* ch, CNetMsg::SP& msg)
{

//after this value
GAMELOG << init("EXPED DEBUG CHANGETYPE REQ", ch)
<< "EXPEDTYPE" << delim << cExpedType << delim
<< "DIVITYPE" << delim << cDiviType << delim
<< end;
// add this

if (cExpedType > MSG_EXPED_TYPE_OPENBOX || cDiviType > MSG_DIVITYPE_SP)
{
CNetMsg::SP rmsg(new CNetMsg);
ExpedErrorMsg(rmsg, MSG_EXPED_ERROR_NOT_EXPED);
SEND_Q(rmsg, ch->m_desc);
return;
}

//next we add somthing here
void do_ExpedMoveGroupReq(CPC* ch, CNetMsg::SP& msg)
//after this
GAMELOG << init("EXPED DEBUG MOVEGROUP REQ", ch)
<< "SOURCE GROUP" << delim << nMoveCharIndex << delim
<< "MOVE CHAR INDEX" << delim << nMoveCharIndex << delim
<< "TARGET GROUP" << delim << nTargetGroup << delim
<< "TARGET CHAR INDEX" << delim << nTargetListindex
<< end;
//add this
if (nSourceGroup >= MSG_EXPED_GROUP_COUNT || nTargetGroup >= MSG_EXPED_GROUP_COUNT)
{
LOG_INFO("Crash teste ????????");
return;
}

//next we add a fix here
void do_ExpendOffline(CPC* ch, CNetMsg::SP& msg)
{
//add this
if( !ch || ch->m_Exped == NULL || ch->m_bProcDisconnect == 0)
{
return;
}



DoFuncParty.cpp:

 

//in this function
void do_PartyChangeType(CPC* ch, CNetMsg::SP& msg)
{
//after this
RefMsg(msg) >> cPartyType // ÀϹÝ(±Õµî),ÀÔŒö¿ìŒ±,ÀüÅõÇü,»óÀÚ¿­±â ±žºÐ
>> cDiviType // °æÇèÄ¡,ŸÆÀÌÅÛ,œºÆäŒÈ ŸÆÀÌÅÛ ±žºÐ
>> cAllOneSet;
//add this
if (cPartyType > MSG_PARTY_TYPE_OPENBOX ||cDiviType > MSG_DIVITYPE_SPECIAL || cAllOneSet > MSG_PARTY_SETALLONE_ONE)
{
CNetMsg::SP rmsg(new CNetMsg);
PartyErrorMsg(rmsg, MSG_PARTY_ERROR_NOT_PARTY);
SEND_Q(rmsg, ch->m_desc);
return;
}
//next fix in this function
void do_PartyOffline(CPC* ch, CNetMsg::SP& msg)
{
//add this
if ( ( !ch && (ch->m_party != NULL)) || (ch->m_party == NULL) || (ch->m_bProcDisconnect == 0))
{
return;
}





warehouse save: ( DBManager_SaveCharacterInfo.cpp)

 

//replace this
std:Confusedtring deleteQuery = boost:Confusedtr(boost::format(
"DELETE FROM t_stash%02d WHERE a_user_idx=%d") % stashIndex % pChar->m_index);
//change to this
std:Confusedtring deleteQuery = boost:Confusedtr(boost::format(
"DELETE FROM t_stash%02d WHERE a_user_idx=%d") % stashIndex % pChar->m_desc->m_index);



DoFuncEtc.cpp (castle crystal outside area)

 

//after this
{
CNetMsg::SP rmsg(new CNetMsg);
CastleErrorMsg(rmsg, MSG_EX_CASTLE_ERROR_MEM_5_FAIL);
SEND_Q(rmsg, ch->m_desc);
return;
}
//add this
CNPC* pLordSymbol = pCastle->GetLordSymbol();
if (pLordSymbol && (GetDistance(GET_X(pLordSymbol), GET_Z(pLordSymbol), GET_H(pLordSymbol), ch) > 12
|| GET_YLAYER(ch) != GET_YLAYER(pLordSymbol)))
{
CNetMsg::SP rmsg(new CNetMsg);
CastleErrorMsg(rmsg, MSG_EX_CASTLE_ERROR_POS_FAIL);
SEND_Q(rmsg, ch->m_desc);
ch->m_desc->IncreaseHackCount(3);
return;
}

Engine/Contents/Base/ChattingUI.cpp

//replace this
int nIndexBuf[32];

//with this
int nIndexBuf[256];



Chat input crash fix.

Engine/Interface/UITextBoxEx.cpp

// in function void CUITextBoxEx:Confusedplit(std:Confusedtring str, CItems* item, int countItems)

//your code will look like this
else
strText = strSyntax;

switch(m_eSplitType)
{
case SPLIT_NONE:

//change it to this
else
strText = strSyntax;

if (strText.empty()) break;

switch(m_eSplitType)
{
case SPLIT_NONE:

//next function we will modify is void CUITextBoxEx::insertBtn( CUITextEx* pTextEx, vecValcont& val, std:Confusedtring&
//you will e looking for this
int nCmd = -1;
int nIndex = -1;
if (nSize >= eTVCMD_INDEX)
{
nCmd = atoi(val[eTVCMD_CMD].c_str());
nIndex = atoi(val[eTVCMD_INDEX].c_str());
//modify the line nSize >= eTVCMD_INDEX
//change it to this
if (nSize > eTVCMD_INDEX)

 

#2

files, screenshots is broken ...

 

#3

fixed thanks. /index.php?/profile/19661-rondo157/&do=hovercard" data-mentionid="19661" href="/index.php?/profile/19661-rondo157/" rel="">@rondo157

#4

Thanks alot really /index.php?/profile/2167-dethunter12/&do=hovercard" data-mentionid="2167" href="/index.php?/profile/2167-dethunter12/" rel="">@dethunter12 this is an Excellent release, i heard alot of rumors about all those dupes that i was already disabling some of them but some of them needed fixing!

THANK YOU FOR ALL THE FIXES AND EXPLANATION!

#5

Amazing dude, everything was pretty clear. I just met some problem with "Area.cpp fix" since you wrote:

//Dupe Fix
if (this->m_RaidDifficulty > 2 || this->m_RaidDifficulty <= -1)
{
this->m_RaidDifficulty = 0;
}

But is not possible call "this" statment in a function which is not "nonstatic" ... probably my fault!?



And in the end was pretty hard to fix the trade agent since the source code was totally different from mine ... i get something like 300/500 errors cause help and subhelper seems to not have the same struct as you ? ... btw ... [CeNsOrEd] amazing work dude +1 for you ❤️



NB: Party.cpp's fixies should be applied in doFuncParty.cpp

#6

updated post and the area.cpp should read like this .

I also added 2 new fixes to the post.

 

m_nMakeNPC = 0;

CNPC* npc;

vec_raidnpcrregenlist_t::iterator it = m_raidNPCRegenList.begin();
vec_raidnpcrregenlist_t::iterator endit = m_raidNPCRegenList.end();
for (; it != endit; ++it)
{
CNPCRegenInfo* p = *(it);
p->m_lastDieTime = gserver->m_pulse + GetRandom(1, p->m_regenSec / 2);
p->m_bAlive = false;
}
if (this->m_RaidDifficulty > 2 || this->m_RaidDifficulty <= -1)
{
this->m_RaidDifficulty = 0;
}
if(m_RaidDifficulty != -1)
m_RaidInfoList[this->m_RaidDifficulty].m_pArea = this;

if(nRaidRoomNum != -1)
m_nRaidRoomNo = nRaidRoomNum;

 

#7

you didnt add [CeNsOrEd] dethfaggot 

#8

I get alot of errors when i apply these fixes in Reza's June Files:

gameserver/pc.cpp

gameserver/ProcHelperMsg.cpp

gameserver/Character.h

gameserver/DoFuncGuild.cpp[/b]

#9

it's because the fixes are inteded for november files ? 

i updated post again with another fix (gold dupe)

#10


1 minute ago, dethunter12 said:




it's because the fixes are inteded for november files ? 

i updated post again with another fix (gold dupe)




Is there a way to implement them in June Files? or are they already fixed in June ones? 

These are only ones i cant implement:

gameserver/pc.cpp

gameserver/ProcHelperMsg.cpp

gameserver/Character.h

gameserver/DoFuncGuild.cpp[/b]



Forum Jump:


Users browsing this thread: 3 Guest(s)