Esempio n. 1
0
int ZipFunc::replace(const DZStrW &d, const DZStrW &s)
{
#ifndef UNICODE
    int             r;
    HINSTANCE       hKernal;
    MoveWithProgress mover;
#endif

    if (Verbose)
        Notify(IVERBOSE, _T("replace '%s' with '%s'"), d.c_str(), s.c_str());
    else
      CB->UserCB(zacTick);  // take a little time

    if (d.IsEmpty() || s.IsEmpty())
    {
        diag(_T("in replace - missing filename"));
		return DZ_ERM_TEMP_FAILED;
    }
#ifdef UNICODE
	if (!MoveFileWithProgress(s.c_str(), d.c_str(), MoveProgress, this,
                  MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING))
    {
	   int re = DZ_ERM_TEMP_FAILED;
		Notify((unsigned)re, _T(" replace: Move failed -[%s]"),  SysMsg().c_str());
        return re;
    }
    return DZ_ERR_GOOD;
#else
    hKernal = LoadLibrary("kernel32.dll");
    if (hKernal == NULL)
        return replaceOrig(d, s);
    mover = (MoveWithProgress) GetProcAddressA(hKernal, "MoveFileWithProgressA");
    if (mover == NULL)
    {
        FreeLibrary(hKernal);
        return replaceOrig(d, s);
    }
    r = DZ_ERR_GOOD;

    CB->UserXItem(100, 2, _T("Copying Temporary File"));
    if (!((mover)(s, d, MoveProgress, this,
                  MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)))
    {
        r = DZ_ERM_TEMP_FAILED;
        Notify(DZ_ERM_TEMP_FAILED, _T(" replace: Move failed [%s]"), SysMsg());
    }

    FreeLibrary(hKernal);
    return r;
#endif
}
void do_Attack(CPC* pc, CNetMsg::SP& msg)
{
	CDratanCastle * pCastle = CDratanCastle::CreateInstance();
	pCastle->CheckRespond(pc);

	RequestClient::doAttack* packet = reinterpret_cast<RequestClient::doAttack*>(msg->m_buf);

	// 동시 공격은 최대 5
	if (packet->multicount > 5)
	{
		LOG_ERROR("HACKING : invalid multi count[%d]. charIndex[%d]", packet->multicount, pc->m_index);
		pc->m_desc->Close("invalid multi count");
		return;
	}

	// multi target의 중복 검사
	if (packet->multicount > 1)
	{
		std::set<int> tset;
		for (int i = 0; i < packet->multicount; ++i)
		{
			if (tset.insert(packet->list[i].index).second == false)
			{
				LOG_ERROR("HACKING : duplicate multi target[%d]. charIndex[%d]", packet->list[i].index, pc->m_index);
				pc->m_desc->Close("duplicate multi target");
				return;
			}
		}
	}

	// 대상 검색 : 인접 셀에서만
	CArea* area = pc->m_pArea;
	if (area == NULL)
		return;

	CCharacter* ch = area->FindCharInCell(pc, packet->aIndex, (MSG_CHAR_TYPE)packet->aCharType);
	if (ch == NULL)
		return;

	CCharacter* tch = area->FindCharInCell(ch, packet->tIndex, (MSG_CHAR_TYPE)packet->tCharType);
	if (tch == NULL)
		return;

	// 공격자가 PC이면 자신의 캐릭만 조정
	if (IS_PC(ch) && ch != pc)
		return ;

	switch (ch->m_type)
	{
	case MSG_CHAR_PC:
		{
			if( IS_NPC(tch))
			{
				CPC * pPC = TO_PC(ch);
				CNPC * pNPC = TO_NPC(tch);
				if( pPC->GetSummonNpc(SUMMON_NPC_TYPE_MERCENARY) == pNPC )
					return;
			}

			//pvp보호 아이템 체크
			if (checkPvPProtect(pc, tch) == false)
				return;

			// 공격 거리 검사
			if (GetDistance(ch, tch) > ch->m_attackRange * 2)
				return ;

			// 공속 검사
			if ( ch->ChekAttackType() && ch->CheckHackAttack(pc))
				return ;

			// 펫 타고 있으면 불가능
			if (pc->GetPet() && pc->GetPet()->IsMount())
				return ;

			// 공성 아이템 착용시 해당 스킬 발동
			int mixSkillIndex[] = { pc->m_opSturnIndex, pc->m_opBloodIndex, pc->m_opPoisonIndex, pc->m_opSlowIndex, pc->m_opMoveIndex };
			int mixSkillLevel[] = { pc->m_opSturnLevel, pc->m_opBloodLevel, pc->m_opPoisonLevel, pc->m_opSlowLevel, pc->m_opMoveLevel };
			CSkill* skillMixItem = NULL;
			int i;
			int bStop = 0;
			for (i = 0; i < 5; i++)
			{
				if (mixSkillIndex[i] > 0 && mixSkillLevel[i] > 0)
				{
					skillMixItem = gserver->m_skillProtoList.Create(mixSkillIndex[i], mixSkillLevel[i]);
					if (skillMixItem)
					{
						bool bApply;
						bStop = ApplySkill(ch, tch, skillMixItem, -1, bApply);
					}
					delete skillMixItem;
					skillMixItem = NULL;
					if (bStop != 0)
						return ;
				}
			}

			if (IS_PC(ch))
			{
				CPC* pPCAttacker = TO_PC(ch);
				CItem* weaponItem = pPCAttacker->m_wearInventory.wearItemInfo[WEARING_WEAPON];

				// 암흑 공격
				if (pPCAttacker->m_opAttackBlind > 0)
				{
					CSkill* pSkillBlind = gserver->m_skillProtoList.Create(415, pPCAttacker->m_opAttackBlind);
					int nRetApplySkill = 0;
					if (pSkillBlind)
					{
						bool bApply;
						nRetApplySkill = ApplySkill(ch, tch, pSkillBlind, -1, bApply);
					}
					delete pSkillBlind;
					pSkillBlind = NULL;
					if (nRetApplySkill != 0)
						return ;
				}

				// 독 공격
				if (pPCAttacker->m_opAttackPoison > 0)
				{
					CSkill* pSkillPoison = gserver->m_skillProtoList.Create(414, pPCAttacker->m_opAttackPoison);
					int nRetApplySkill = 0;
					if (pSkillPoison)
					{
						bool bApply;
						nRetApplySkill = ApplySkill(ch, tch, pSkillPoison, -1, bApply);
					}
					delete pSkillPoison;
					pSkillPoison = NULL;
					if (nRetApplySkill != 0)
						return ;
				}
			}
		} // PC 검사

		break;

	case MSG_CHAR_PET:
	case MSG_CHAR_ELEMENTAL:
		// TODO : 소환수 공속 검사
		// 공격 거리 검사
		if (GetDistance(ch, tch) > ch->m_attackRange * 2)
			return ;

		// 공속 검사
		if (ch->CheckHackAttack(pc))
			return ;

		break;

	default:
		break;
	}

	if(IS_PC(tch))
	{
		if( TO_PC(tch)->m_bImmortal == true )
			return;
	}

	if (DEAD(ch) || !ch->CanAttack() || pc->IsDisable())	return ;
	// 결계걸린 대상은 공격 못한다.
	if ( tch->m_assist.m_state & AST_FREEZE )	return;
	//무적 버프 대상은 공격할 수 없다.
	if ( tch->m_assist.m_state & AST_SAFEGUARD )
	{
		CNetMsg::SP rmsg(new CNetMsg);
		SysMsg(rmsg, MSG_SYS_DO_NOT_ATTACK_IMMOTAL);
		SEND_Q(rmsg, pc->m_desc);
		return;
	}


	// 대상이 NPC일때만 멀티 공격
	if (!IS_NPC(tch))
		packet->multicount = 0;

	// 최소한 공격 1회 이상
	bool bAttacked = false;
	bool bAttackedPet = false;		// 애완동물은 NPC상대시 레벨 검사

	// 멀티 공격 검사용
	std::set<int> listMultiTarget;

	while (tch)
	{
		bool bBlocked = false;

		// NPC를 공격할 때에만 속성맵 검사 (프리PK 지역이 아닐때만)
		if ( IS_NPC(tch) && !(tch->GetMapAttr() & MATT_FREEPKZONE) )
		{
			char tempy = GET_YLAYER(ch);
			bBlocked = (!area->IsNotBlocked(ch, tch, true, tempy));
		}

		int ret = 0;
		if (!bBlocked)
		{
			if (IS_PC(ch) && ch->IsEnemy(tch))
			{
				bAttacked = true;
#ifdef MONSTER_AI
				if (tch != NULL	&& IS_NPC(tch))
				{
					CNPC * pTemp = TO_NPC(tch);
					if (pTemp != NULL)
					{
						if (ch->m_level - tch->m_level <= 5 && pTemp->m_proto->m_index != 303 /*악마의 묘지*/)
						{
							bAttackedPet = true;
						}

						if (pTemp->m_bMoveLock || pTemp->m_bMoveToRegen)
						{
							pTemp->m_bMoveToRegen = false;
							pTemp->m_bMoveLock = false;
							pTemp->m_pulseMoveLock = 0;
							pTemp->m_postregendelay = 0;
						}
					}
				}
#else
				if (tch != NULL	&& IS_NPC(tch) && ch->m_level - tch->m_level <= 5)
				{
					CNPC * pTemp = TO_NPC(tch);
					if (pTemp != NULL && pTemp->m_proto->m_index != 303 /*악마의 묘지*/)
					{
						bAttackedPet = true;
					}
				}
#endif
			}

			listMultiTarget.insert(tch->m_index);
			ret = ProcAttack(ch, tch, ch->GetAttackType(NULL), NULL, 0);
		}

		if (ret == -1 || tch->m_index == -1) // ProcAttack()안에서 Character 객체가 소멸된 경우도 포함
		{
			tch = NULL;
			continue ;
		}

		//공격 발동형 스킬 추가
		if( pc->m_optionAttSkillList.count() > 0 )
		{
			//공격 할 시에 적에게 스킬 적용
			void* pos = pc->m_optionAttSkillList.GetHeadPosition();
			bool bApply = false;
			while (pos)
			{
				CSkill* skill = pc->m_passiveSkillList.GetNext(pos);
				if (skill && skill->m_proto)
				{
					int rand = GetRandom(1, 10000);
					if( rand < skill->m_optionSkillProb )
					{
						ApplySkill(ch, tch, skill, -1, bApply);
						if(bApply == false)
						{
							GAMELOG << init("EVENT_PCBANG_2NDS SKILL FAILED (LOGIN) ", pc ) << end;// 스킬 적용 실패
						}
					}
				}
			}
		}

		if (area->m_zone->IsPersonalDungeon() == false)
		{
			tch = NULL;
			continue;
		}

		if (packet->multicount && !DEAD(ch))
		{
			int multitarget = packet->list[packet->multicount].index;
			--packet->multicount;

			tch = area->FindCharInCell(ch, multitarget, (MSG_CHAR_TYPE)packet->tCharType);
			if (tch == NULL)
			{
				continue;
			}

			if (GetDistance(ch, tch) > ch->m_attackRange * 2)
			{
				tch = NULL;
				continue;
			}

			std::set<int>::iterator it = listMultiTarget.find(tch->m_index);
			if (it != listMultiTarget.end())
			{
				GAMELOG << init("HACK ATTACK MULTI TARGET", pc)
						<< "ZONE" << delim
						<< pc->m_pZone->m_index << delim
						<< "TARGET" << delim
						<< packet->tCharType << delim
						<< multitarget
						<< end;

				if (pc->m_desc->IncreaseHackCount(1))
					return ;

				tch = NULL;
			}
		}
		else
		{
			tch = NULL;
			continue;
		}

		if (packet->multicount <= 0)
		{
			tch = NULL;
			continue;
		}
	} // end while

	if (bAttackedPet && !ch->IsInPeaceZone(true))
		pc->m_pulseLastAttackSkill = gserver->m_pulse;

#ifdef EVENT_SEARCHFRIEND_TIME
	// 공격시 이벤트 시간 갱신 검사
	if (gserver->m_bSearchFriendEvent && (pc->m_nEventSearchFriendListCount >= 1)
			&& (pc->m_bEventSearchFriendSelect == true) && (pc->m_nTimeEventSearchFriend <= 216000)
			&& bAttacked && !ch->IsInPeaceZone(true))
		pc->m_pulseEventSearchFriend = gserver->m_pulse;
#endif // #ifdef EVENT_SEARCHFRIEND_TIME
}
Esempio n. 3
0
/* ===========================================================================
 *                     Function do_seekable()
 * return PK-type error code */
int UnzOpr::do_seekable(int lastchance)
{
	/* static int no_ecrec = FALSE;  SKM: moved to globals.h */
	ulg sig;
	struct stati64 stt64;
	int maybe_exe = false;
	int too_weird_to_continue = false;
	int error = 0, error_in_archive;

	if (Verbose < 0)
		Notify(ITRACE, _T("starting do_seekable"));

	/* ---------------------------------------------------------------------------
	 * Open the zipfile for reading in BINARY mode to prevent CR/LF translation,
	 * which would corrupt the bit streams.
	 *--------------------------------------------------------------------------- */
	if (_tstati64(fzipfn.c_str(), &stt64) || (error = S_ISDIR(stt64.st_mode)) != 0)
		return error ? IZ_DIR : PK_NOZIP;

	fziplen = stt64.st_size;

	if (stt64.st_mode & S_IEXEC)
		maybe_exe = true;
	/* might find unzip, not unzip.zip; etc. */

	if (Verbose) // < 0)
		Notify(ITRACE, _T("opening zip file; fname=%s"), fzipfn.c_str());
	fUnzInfile = NULL;
	AutoStream uzfile(&fUnzInfile);

	fUnzInfile = new ZFile(this, fzipfn,
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS);
	if (!uzfile.Stream()->IsOpen())
	{
		if (Verbose < 0)
			Notify(ITRACE, _T("could not open: %s [%s]"), fzipfn.c_str(),
			SysMsg().c_str());

		throw DZException(DZ_ERM_ERROR_CREATE);
	}

	if (Verbose < 0)
		Notify(ITRACE, _T("zip file %s opened OK"), fzipfn.c_str());
	/* the stat() test above, but... */
	// if (Verbose < 0)
	// Notify(ITRACE, "do_seekable, loc 3");

	/* ---------------------------------------------------------------------------
	 * Find and process the end-of-central-directory header.  UnZip need only
	 * check last 65557 bytes of zipfile:  comment may be up to 65535, end-of-
	 * central-directory record is 18 bytes, and signature itself is 4 bytes;
	 * add some to allow for appended garbage.
	 *--------------------------------------------------------------------------- */

	fcur_zipfile_bufstart = 0;
	finptr = finbuf;

#ifdef TIMESTAMP
	if (!fqflag && !fT_flag)
#else
		if (!fqflag)
#endif

			Notify(0, _T("Archive:  %s"), fzipfn.c_str());

	if (Verbose < 0)
		Notify(ITRACE, _T("do_seekable, loc 4"));
	if ((((error_in_archive = find_ecrec(MIN(fziplen, 66000L))) != 0 ||
				((error_in_archive = uz_end_central()) != 0 && DZ_ERR
					(error_in_archive) != PK_WARN))))
	{
		delete fUnzInfile;
		fUnzInfile = NULL;

		if (maybe_exe)
			Notify(0, _T("maybe an EXE file: %s"), fzipfn.c_str());
		if (lastchance)
			return error_in_archive;
		else
		{
			fno_ecrec = true;
			/* assume we found wrong file:  e.g., */
			return PK_NOZIP;
			/* unzip instead of unzip.zip */
		}
	}

	if (Verbose < 0)
		Notify(ITRACE, _T("do_seekable, loc 5"));
	if (fzflag > 0)
	{
		delete fUnzInfile;
		fUnzInfile = NULL;
		return error_in_archive;
	}

	/* ---------------------------------------------------------------------------
	 * Test the end-of-central-directory info for incompatibilities (multi-disk
	 * archives) or inconsistencies (missing or extra bytes in zipfile).
	 *--------------------------------------------------------------------------- */
#ifdef NO_MULTIPART
	error = (fecrec.number_this_disk == 1) && (fecrec.num_disk_start_cdir == 1);
#else
	error = (fecrec.number_this_disk != 0);
#endif
#ifdef NO_MULTIPART /* concatenation of multiple parts works in some cases */
	// else
	if (!error && fecrec.number_this_disk != 0)
	{
		DZError(DZ_ERM_ZIP_MULTI);
		error_in_archive = PK_FIND;
		too_weird_to_continue = true;
	}
#endif

	if (Verbose < 0)
		Notify(ITRACE, _T("do_seekable, loc 6"));
	if (!too_weird_to_continue)
	{
		/* (relatively) normal zipfile:  go for it */
		if (error)
		{
			Notify(0, _T("maybe a pak bug in %s"), fzipfn.c_str());
			error_in_archive = PK_WARN;
		}

		if ((fextra_bytes = freal_ecrec_offset - fexpect_ecrec_offset) < 0L)
		{
			Notify(0, _T("missing bytes in zipfile"));
			error_in_archive = PK_ERR;
		}
		else if (fextra_bytes > 0)
		{
			if ((fecrec.offset_start_central_directory == 0) &&
				(fecrec.size_central_directory != 0))
			{
				/* zip 1.5 -go bug */
				Notify(0, _T("NULL central dir"));
				fecrec.offset_start_central_directory = fextra_bytes;
				fextra_bytes = 0;
				error_in_archive = PK_ERR;
			}
			else
			{
				Notify(0, _T("Warning: extra bytes at start of zipfile"));
				error_in_archive = PK_WARN;
			}
		}

		/* -----------------------------------------------------------------------
		 *       Check for empty zipfile and exit now if so.
		 *----------------------------------------------------------------------- */
		if (Verbose < 0)
			Notify(ITRACE, _T("do_seekable, loc 7"));
		if (fexpect_ecrec_offset == 0L && fecrec.size_central_directory == 0)
		{
			Notify(0, _T("Empty zipfile"));
			delete fUnzInfile;
			fUnzInfile = NULL;
			return PK_ERR_NOWARN(error_in_archive) ? error_in_archive : PK_WARN;
		}

		/* -----------------------------------------------------------------------
		 * Compensate for missing or extra bytes, and seek to where the start
		 * of central directory should be.  If header not found, uncompensate
		 * and try again (necessary for at least some Atari archives created
		 * with STZip, as well as archives created by J.H. Holm's ZIPSPLIT 1.1).
		 *----------------------------------------------------------------------- */
		zlseek(fecrec.offset_start_central_directory);
#ifdef OLD_SEEK_TEST
		if (readbuf((char*) & sig, 4) == 0)
		{
			close(fzipfd);
			fzipfd = 0;
			/* RCV added 29-1-99 */
			return PK_ERR;
			/* file may be locked, or possibly disk error(?) */
		}

		if (strncmp(fsig, fcentral_hdr_sig, 4))
#else
			if ((readbuf((char*) & sig, 4) == 0) || sig != CentralFileHeaderSig)
#endif
			{
				if (Verbose < 0)
					Notify(ITRACE, _T("central dir found"));
				fextra_bytes = 0;
				zlseek(fecrec.offset_start_central_directory);
				if ((readbuf((char*) & sig, 4) == 0)
					|| sig != CentralFileHeaderSig)
				{
					DZError(DZ_ERM_NO_CENTRAL);
					delete fUnzInfile;
					fUnzInfile = NULL;

					return PK_BADERR;
				}

				Notify(0, _T("central dir too long"));
				error_in_archive = PK_ERR;
			}

		/* -----------------------------------------------------------------------
		 * Seek to the start of the central directory one last time, since we
		 * have just read the first entry's signature bytes; then list, extract
		 * or test member files as instructed, and close the zipfile.
		 *----------------------------------------------------------------------- */
		if (Verbose < 0)
			Notify(ITRACE, _T("about to extract files (error = %d)"),
			error_in_archive);
		zlseek(fecrec.offset_start_central_directory);
		// GO DO EXTRACT OR TEST
		error = extract_or_test_files();
		/* EXTRACT OR TEST 'EM */

		if (Verbose < 0)
			Notify(ITRACE, _T("Done with extract/list files (error = %d)"),
			error);
		if (error > error_in_archive) /* don't overwrite stronger error */
				error_in_archive = error;
		/* with (for example) a warning */
	}
	/* end if (!too_weird_to_continue) */

	delete fUnzInfile;
	fUnzInfile = NULL;

	return error_in_archive;
}
Esempio n. 4
0
int ZipOp::ZipStreamStream(void)
{
    fwindow_size = 0L;

    if (fGEncrypt)
    {
        fkey = fGPassword;

        if (!fkey || !*(fkey))
        {
            // use global
            if (GetUserPW() != DZ_ERR_GOOD)
                return -1;  // error

            fkey = fuser_key;
        }
    }

    fZipInfile = new ZStream(this, _T("0:<INSTREAM>"), fSS->fSSInput);

    AutoStream inz(&fZipInfile);
    fimax = fSS->Size;
    fcrc = crc32(0L, NULL, 0);
    fisize = 0;
    CB->SetArg1(1);
    CB->UserCB(zacCount);

    // Pass total filesize.
    CB->SetFileSize(fimax);
    CB->UserCB(zacSize);
    ulg f_crc = 0;
    __int64 fsz = 0;
    bool haveCRC = false;

    if (fkey)
    {
        if (!fNoPrecalc)
        {
            if (Verbose < 0)
                Notify(ITRACE,  _T("about to call Precalculate CRC"));

            // +++++ get CRC before we start
			CB->UserXItem(fimax, 13, _T("*PreCalculate"));
            __int64 pos1 = 0;

            if (!fZipInfile->IsFile)
                pos1 = fZipInfile->SetPosition(0, FILE_CURRENT); // get start posn

			f_crc = crc32(0L, NULL, 0);
            unsigned long byts;

            while (true)
            {
                unsigned ToRead = sizeof(fwindow);

                if (fimax > 0 && (fsz + ToRead) > fimax)
                {
                    ToRead = (unsigned)(fimax - fsz);

                    if (!ToRead)
                        break;
                }

                if (!fZipInfile->Read(fwindow, ToRead, &byts) || !byts)
                    break;

				fsz += byts;
				f_crc = crc32(f_crc, (const uch*)fwindow, (int)byts);
				CB->UserXProgress(byts, 13);

                if (Abort_Flag)
					Fatal(DZ_ERM_ABORT, 0);
            }

            fSS->CRC = f_crc;

            haveCRC = true;
            // reposition

            if (fZipInfile->SetPosition(pos1, FILE_BEGIN) != pos1)
            {
                if (Verbose)
					Notify(IVERBOSE, _T("Could not reposition %s [%s]"),
						fZipInfile->fname.c_str(), SysMsg().c_str());

				return  DZError(DZ_ERM_ERROR_SEEK);
			}

            if (fimax > fsz)
                fimax = fsz;
        }

        // ----- get CRC before we start
        // Since we do not yet know the crc here, we pretend that the crc is the
        //   modification time:
//    if (!haveCRC)
//      fSS->CRC = z->tim << 16;
        if (Verbose < 0)
            Notify(ITRACE,  _T("using supplied CRC %lu"), fSS->CRC);
    }

    // connect to output
    fZipOutfile = new ZStream(this, _T("0:<OUTSTREAM>"), fSS->fSSOutput);

    AutoStream outz(&fZipOutfile);

    CB->UserItem(fimax, _T("<INSTREAM>"));

	if (fkey)
		crypthead(fkey, fSS->CRC);  // write

    // Write stored or deflated file to zip file
    fSS->Method &= 0xFF;

    if (fSS->Method != DEFLATE)
        fSS->Method = 0;

    if (flevel < 1)
        fSS->Method = 0;

	int mthd = (int)fSS->Method;

    if (mthd == DEFLATE)
    {
        if (Verbose < 0)
            Notify(ITRACE,  _T("about to call Deflate"));

        bi_init();
        ush att = BINARY;
        ush flg = FLAG_ENCRYPT_BIT;

        // will be changed in deflate()
        ct_init(&att, &mthd);
        lm_init(flevel, &flg);

        // PERFORM THE DEFLATE
        fSS->Size = deflate();

        if (Abort_Flag)
			Fatal(DZ_ERM_ABORT, 0);
    }
    else
    {
        int k;

        if (Verbose)
            Notify(IVERBOSE, _T("Storing %s "), fZipInfile->fname.c_str());

        while ((k = read_buf(fwindow, sizeof(fwindow))) > 0
                && k != EOF)
        {
            if (Abort_Flag)
				Fatal(DZ_ERM_ABORT, 0);

			if (!zfwrite(fwindow,  (extent)k))
				return DZ_ERM_TEMP_FAILED;
        }

    }
    /*  Finished Item */
    CB->UserItem(-1, _T("<INSTREAM>")); // mark end of item
    CB->UserCB(zacEndOfBatch); // done with stream compression

    if (haveCRC)
    {
        if (f_crc != fcrc)
            Notify(DZ_ERR_ERROR_READ | IWARNING, _T(" File CRC changed while zipping: %s"),
                   fZipInfile->fname.c_str());

        if (fisize != fsz)
            Notify(DZ_ERR_ERROR_READ | IWARNING, _T(" File size changed while zipping: %s"),
                   fZipInfile->fname.c_str());
    }

    fSS->Size = fisize;

    fSS->CRC = fcrc;
    fSS->Method = (DWORD)mthd | (fkey ? 0xff00 : 0);
    return DZ_ERR_GOOD;
}
void do_Action(CPC* ch, CNetMsg::SP& msg)
{
	CDratanCastle * pCastle = CDratanCastle::CreateInstance();
	pCastle->CheckRespond(ch);

	RequestClient::action* packet = reinterpret_cast<RequestClient::action*>(msg->m_buf);

	//인존안에서 (펫)고속이동 사용 불가
	if(ch->m_nJoinInzone_ZoneNo >=0 && ch->m_nJoinInzone_RoomNo >= 0)
	{
		if(packet->index == 38)
			return;
	}

	switch (packet->type)
	{
	case ACTION_GENERAL:
		{
			switch (packet->index)
			{
			case AGT_SITDOWN:				// 앉기 서기
			case AGT_PET_SITDOWN:			// 펫 앉기 서기
				{
					// 죽은 상태면 무시
					if (DEAD(ch) || ch->m_personalshop != NULL || ch->IsSetPlayerState(PLAYER_STATE_CHANGE))
						return ;

					// 펫 앉기 서기 등기면 펫을 타고 있어야 함
					if (packet->index == AGT_PET_SITDOWN)
					{
						if (!ch->GetPet() || !ch->GetPet()->IsMount())
							return ;
					}

					if (!ch->IsSetPlayerState(PLAYER_STATE_SITDOWN))
					{
						if (ch->m_currentSkill)
						{
							ch->m_currentSkill->Cancel(ch);
							ch->m_currentSkill = NULL;
						}
						ch->ResetPlayerState(PLAYER_STATE_MOVING);
					}
					ch->TogglePlayerState(PLAYER_STATE_SITDOWN);
					ch->CalcStatus(true);
				}
				break;

			case AGT_PKMODE:			// 평화/대결 모드
				{
#ifdef BLOCK_PVP
					return;
#else
					if ( gserver->m_bNonPK )
						return;

					if (DEAD(ch) || ch->m_personalshop != NULL)
						return ;

					if (ch->m_pZone->m_index == ZONE_GUILDROOM)
						return;

					if (ch->m_assist.FindBySkillIndex(PVP_PROTECT_SKILL_INDEX) != 0)
					{
						CNetMsg::SP rmsg(new CNetMsg);
						SysMsg(rmsg, MSG_SYS_DO_NOT_PLAY_PVP);
						SEND_Q(rmsg, ch->m_desc);
						return;
					}

					if (ch->m_level <= PKMODE_LIMIT_LEVEL)
					{
						bool bSkipLevel = false;
						// 공성 진행 중 공성 지역 내에서는 저레벨도 PK 가능
						if (ch->m_pZone->m_index == CWarCastle::GetCurSubServerCastleZoneIndex() && ch->GetMapAttr() & MATT_WAR)
						{
							CWarCastle* castle = CWarCastle::GetCastleObject(ch->m_pZone->m_index);
							if (castle && castle->GetState() != WCSF_NORMAL)
							{
								bSkipLevel = true;
							}
						}

						if (!bSkipLevel)
						{
							CNetMsg::SP rmsg(new CNetMsg);
							SysMsg(rmsg, MSG_SYS_PKMODE_LIMITLEVEL);
							SEND_Q(rmsg, ch->m_desc);
							return;
						}
					}

					if (ch->IsSetPlayerState(PLAYER_STATE_PKMODEDELAY) || ch->IsSetPlayerState(PLAYER_STATE_RAMODE) || ch->IsSetPlayerState(PLAYER_STATE_CHANGE))
						return ;

					if (ch->IsInPeaceZone(true))
						return ;

					if (ch->GetMapAttr() & MATT_FREEPKZONE)
						return ;

					// PVP 아레나 존이면은 프리피케이 공간 말고는 모두 pk모드가 안되게 막음..   yhj
					if ( !(ch->GetMapAttr() & MATT_FREEPKZONE)
							&& !(ch->GetMapAttr() & MATT_PEACE)
							&& ch->m_pZone->m_index == ZONE_PK_TOURNAMENT )
					{
						return ;
					}

					// 스트레이아나 마을 계단에서 pk모드가 안되게 막음..   yhj
					// 다음 좌표는 스트레이아나 마을의 내부좌표
					if ( (ch->GetMapAttr() & MATT_STAIR_UP || ch->GetMapAttr() & MATT_STAIR_DOWN )
							&& ch->m_pZone->m_index == ZONE_STREIANA
							&& GET_X(ch) >= 940.0 && GET_X(ch) <= 1090.0
							&& GET_Z(ch) >= 515.0 && GET_Z(ch) <= 695.0 )
					{
						return ;
					}

					if (ch->m_pZone->IsOXQuizRoom())
					{
						CNetMsg::SP rmsg(new CNetMsg);
						SysMsg(rmsg, MSG_SYS_DO_NOT_CHANGE_PK_MODE);
						SEND_Q(rmsg, ch->m_desc);
						return ;
					}

					if (ch->m_pZone->isRVRZone())
					{
						CNetMsg::SP rmsg(new CNetMsg);
						SysMsg(rmsg, MSG_SYS_DO_NOT_CHANGE_PK_MODE);
						SEND_Q(rmsg, ch->m_desc);
						return ;
					}

					if (ch->IsSetPlayerState(PLAYER_STATE_PKMODE))
					{
						ch->SetPlayerState(PLAYER_STATE_PKMODEDELAY);
						ch->m_pkmodedelay = PULSE_PKMODE_DELAY;
					}
					else
					{
						ch->TogglePlayerState(PLAYER_STATE_PKMODE);
						ch->CancelInvisible();
					}
#endif
				}
				break;

			case AGT_THROW_WATER:
				{
					if( !gserver->isActiveEvent(A_EVENT_SONGKRAN) )
						return;

					CCharacter* tch = ch->m_pArea->FindCharInCell( ch, packet->targetIndex, MSG_CHAR_PC, true );
					if( tch == NULL )
					{
						return;
					}

					CSkill* skill = new CSkill( gserver->m_skillProtoList.Find( 436 ), 1 );
					bool bApply;
					ApplySkill( ch, tch, skill, -1, bApply );
					delete skill;
				}

				break;
			} // end switch
		}
		break;

	case ACTION_SOCIAL:
	case ACTION_PARTY:
	case ACTION_GUILD:
	case ACTION_TITLE:
		break;

	default:
		{
			LOG_ERROR("HACKING : invalid action type[%d]. charIndex[%d]", packet->type, ch->m_index);
			ch->m_desc->Close("invalid action type");
			return;
		}
	} // end switch

	{
		CNetMsg::SP rmsg(new CNetMsg);
		ResponseClient::makeAction(rmsg, ch, packet->type, packet->index);
		ch->m_pArea->SendToCell(rmsg, ch, true);
	}
}
Esempio n. 6
0
bool CAPet::TransFormationCheck()
{
	if( m_pProto->m_TansType !=  APET_TRANS_NONE )
	{
		int comp = 0;
		char oldState = this->m_cTransSate;

		switch( m_pProto->m_TansType)
		{
		case APET_TRANS_TIME:
			{
				int nowsec = gserver->getNowSecond() % 3600;

				if (nowsec == (3600 - 30) || nowsec == (3600 / 2) - 30)	// 30초 전
				{
					CNetMsg::SP rmsg(new CNetMsg);
					SysMsg(rmsg, MSG_SYS_TRANSLATE_START );
					SEND_Q(rmsg, m_pOwner->m_desc);
				}
				else if (nowsec >= 0 && nowsec <= (3600 / 2)) // 정각s
				{
					m_cTransSate = 0;
				}
				else
				{
					m_cTransSate = 1;
				}
			}
			break;
		case APET_TRANS_FAITH:
			comp = m_nFaith;
			break;
		case APET_TRANS_STM:
			comp = m_nStm;
			break;
		}

		// 옵션이 0 또는 100 이상일때 강제로 설정해주는 부분
		if( m_cForceTrans == 1 )			// 무조건 변신
			this->m_cTransSate = 1;
		else if ( m_cForceTrans == 2 )		// 무조건 변신 안함
			this->m_cTransSate = 0;

		if( oldState != m_cTransSate )
		{
			// 변신했는데 마운트 타입이 아닌경우
			if( m_pProto->m_nMount[ (unsigned int)m_cTransSate ] < 1 && IsMount() )
			{
				Mount(false);
			}
			else
			{
				CArea* area = m_pOwner->m_pArea;

				{
					CNetMsg::SP rmsg(new CNetMsg);
					DisappearMsg(rmsg, this);
					area->SendToCell(rmsg, this, true);
				}

				{
					CNetMsg::SP rmsg(new CNetMsg);
					AppearMsg(rmsg, this);
					area->SendToCell(rmsg, this, true);
				}
			}

			CalcStatus(false);

			return true;
		}
	}
	return false;
}
Esempio n. 7
0
int ZipFunc::replaceOrig(const DZStrW &d, const DZStrW& s)
{
    struct stati64 t;        // results of stat()
    int         copy = 0;
    int         d_exists;

	d_exists = _tstati64(d, &t) == 0;
	if (d_exists)
	{
		// respect existing soft and hard links!
		if (t.st_nlink > 1)
			copy = 1;
        else
        {
            if (_tunlink(d))
                return DZ_ERM_ERROR_CREATE;      // Can't erase zip file--give up
            Sleep(5);
        }
    }
    if (!copy)
    {
            // Just move s on top of d
        if (_trename(s, d))// !MoveFile(s, d))
        {
            if (Verbose < 0)
                Notify(IERROR, _T(" replace failed %s (%s)"), s, errno);
            copy = 1;                   // failed ?
            if (errno != ENOTSAM)
				return DZ_ERM_ERROR_CREATE;
        }
    }

    if (copy)
    {
        HANDLE  f,
        g;                    // source and destination files
        int     r;                    // temporary variable
        diag(_T("in replace - open for read"));

        if ((f = CreateFile(s, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL)) <= 0)
        {
            diag(_T("in replace - bad open for Read"));
            Notify(0, _T(" replace: can't open %s [%s]"), s, SysMsg());

			return DZ_ERM_TEMP_FAILED;
        }

        diag(_T("in replace - fopen for write"));

        if ((g = CreateFile(d, GENERIC_WRITE, 0, NULL, CREATE_NEW,
                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL)) <= 0)
        {
            Close_Handle(&f);
            diag(_T("in replace - bad open for Write"));
			return DZ_ERM_ERROR_CREATE;
        }

        r = filecopy(f, g);

        Close_Handle(&f);
        if (!Close_Handle(&g) || r != DZ_ERR_GOOD)
        {
            DeleteFile(d);
            return r ? (DZ_ERR(r) == DZ_ERR_TEMP_FAILED ? DZ_ERR_ERROR_WRITE : r) : DZ_ERM_ERROR_WRITE;
        }

        DeleteFile(s);
    }

    return DZ_ERR_GOOD;
}
bool local_useCashItem_1519(CPC* ch, CItem* item, bool bprolong, RequestClient::doItemUse* packet)
{
	// 1. nPetIndex 아이템 찾고
	// 2. 펫 착용 해제 상태인지 보고
	// 3. 해당 아이템의 펫을 찾고
	// 4. 펫의 타입과 스킬 검사하고
	// 5. 펫 마운트 취소후
	// 6. 펫 상태 알리고
	// 7. 결과 알림
	int extra1 = packet->extra_1;
	bool bFail = false;

	// 1. extra1으로 아이템 찾고
	CItem* pItemPet = ch->m_inventory.FindByVirtualIndex(extra1);
	if (!pItemPet)
		bFail = true;

	// 2. 펫 착용 해제 상태인지 보고
	else if (pItemPet->getWearPos() != WEARING_NONE)
		bFail = true;
	else
	{
		// 3. 해당 아이템의 펫을 찾고
		CPet* pPet = ch->GetPet(pItemPet->getPlus());
		if (!pPet)
			bFail = true;

		// 4. 펫의 타입과 스킬 검사하고
		else if (!pPet->IsMountType() || pPet->GetSkillList()->count() > 1)
			bFail = true;

		else
		{
			// TODO : petlog
			GAMELOG << init("PET RESET MOUNT", ch)
					<< "PET ITEM" << delim
					<< itemlog(pItemPet) << delim
					<< "PET" << delim
					<< pPet->GetPetTypeGrade() << delim
					<< "INDEX" << delim
					<< pPet->m_index << delim
					<< "LEVEL" << delim
					<< pPet->m_level
					<< end;

			pPet->SetPetColor( (char)NON_COLOR );

			{
				CNetMsg::SP rmsg(new CNetMsg);
				HelperPetColorChange( rmsg, ch->m_index, pPet->m_index, (char)NON_COLOR );
				SEND_Q( rmsg, gserver->m_helper );
			}

			// 5. 펫 마운트 취소후
			pPet->ResetMountType();

			{
				// 6. 펫 상태 알리고
				CNetMsg::SP rmsg(new CNetMsg);
				ExPetStatusMsg(rmsg, pPet);
				SEND_Q(rmsg, ch->m_desc);
			}
		}
	}

	// 7. 결과 알림
	if (bFail)
	{
		CNetMsg::SP rmsg(new CNetMsg);
		SysMsg(rmsg, MSG_SYS_CANNOT_RESET_MOUNT);
		SEND_Q(rmsg, ch->m_desc);
		return false;
	}
	else
	{
		CNetMsg::SP rmsg(new CNetMsg);
		SysMsg(rmsg, MSG_SYS_RESET_MOUNT);
		SEND_Q(rmsg, ch->m_desc);
		return true;
	}
}
bool local_useCashItem_1540(CPC* ch, CItem* item, bool bprolong, RequestClient::doItemUse* packet)
{
	int extra1 = packet->extra_1;

	CItem*		pItemClothes = NULL;
	CItem*		pItemEquip = NULL;

	// 1. nIndexClothes로 아이템 찾기
	// 2. 아이템 합성 여부 검사
	// 3. 합성된 아이템 찾기
	// 4. 분리 처리
	// 5. 게임 로그
	// 6. 결과 알림

	// 1. nIndexClothes로 아이템 찾기
	pItemClothes = ch->m_inventory.FindByVirtualIndex(extra1);
	if (pItemClothes == NULL)
	{
		CNetMsg::SP rmsg(new CNetMsg);
		SysMsg(rmsg, MSG_SYS_CANNOT_SEPARATE_ITEM);
		SEND_Q(rmsg, ch->m_desc);
		return false;
	}

	// 관련 수정... m_used == -1 이면 무한인데 여기서 분리가 안되게 되어있음
	// 고로 m_used == -1 이면 건너 뛰게 수정
	// 2. 아이템 합성 여부 검사
	if (	   (pItemClothes->m_itemProto->getItemFlag() & ITEM_FLAG_COMPOSITE)
			   && ( pItemClothes->getUsed() == -1 || pItemClothes->getUsed() > gserver->getNowSecond() )
			   && pItemClothes->getFlag() & FLAG_ITEM_COMPOSITION
	   )
	{
		// 3. 합성된 아이템 찾기
		pItemEquip = ch->m_inventory.FindByVirtualIndex(pItemClothes->m_nCompositeItem);
		if (!pItemEquip)
		{
			CNetMsg::SP rmsg(new CNetMsg);
			SysMsg(rmsg, MSG_SYS_CANNOT_SEPARATE_ITEM);
			SEND_Q(rmsg, ch->m_desc);
			return false;
		}

		// 4. 분리 처리
		pItemClothes->setFlag(pItemClothes->getFlag() & ~FLAG_ITEM_COMPOSITION);
		pItemEquip->setFlag(pItemEquip->getFlag() & ~FLAG_ITEM_COMPOSITION);
		pItemClothes->m_nCompositeItem = -1;
		pItemClothes->setPlus(0);
		pItemClothes->setFlag(FLAG_ITEM_PLATINUM_SET(pItemClothes->getFlag(), 0));

		pItemClothes->setUsed_2(-1);		// 결합 주문서 만료 시간 제거

		// 5. 게임 로그
		GAMELOG << init("ITEM COMPOSITE SEPARATE", ch)
				<< "CLOTHES" << delim
				<< itemlog(pItemClothes) << delim
				<< "EQUIP" << delim
				<< itemlog(pItemEquip)
				<< end;

		{
			// 6. 결과 알림
			CNetMsg::SP rmsg(new CNetMsg);
			SysSeparateItemMsg(rmsg, pItemClothes->getDBIndex());
			SEND_Q(rmsg, ch->m_desc);
		}

		ch->m_inventory.sendOneItemInfo(pItemClothes);
		ch->m_inventory.sendOneItemInfo(pItemEquip);

		ch->CalcStatus(true);

		return true;
	}

	return false;
}
// 감정된 결합 주문서 사용
int local_useCashItem_2665_Sub(CPC* ch, CItem* item, bool bprolong, RequestClient::doItemUse* packet)
{
	int extra1 = packet->extra_1;
	int extra2 = packet->extra_2;

	CItem* pItemClothes = ch->m_inventory.FindByVirtualIndex(extra1);
	CItem* pItemEquip   = ch->m_inventory.FindByVirtualIndex(extra2);

	if (pItemClothes == NULL || pItemEquip == NULL || pItemClothes == pItemEquip || pItemClothes == item || pItemEquip == item)
		return 1;

	// pItemClothes 검사
	// 1. ITEM_FLAG_COMPOSITE		ON
	// 2. FLAG_ITEM_COMPOSITION		OFF
	// 3. USED						< NOW
	// 4. PLUS						NOT SET
	// 5. COMPOSITEITEM				NOT SET
	// 6. WEARPOS					OFF
	if (!(pItemClothes->m_itemProto->getItemFlag() & ITEM_FLAG_COMPOSITE))
		return 2;
	if (pItemClothes->getFlag() & FLAG_ITEM_COMPOSITION)
		return 3;
	if (pItemClothes->getUsed() < gserver->getNowSecond())
	{
		// pItemClothes->m_used == -1 일 경우 기간 무제한 yhj
		// 피닉스 이벤트 아이템이 아닐경우
		if( pItemClothes->getUsed() == -1 )
		{
			/* 무제한 이므로 넘어감*/
		}
		else
		{
			return 4;
		}
	}
	if (pItemClothes->getPlus() != 0)
		return 5;
	if (pItemClothes->m_nCompositeItem >= 0)
		return 6;
	if (pItemClothes->getWearPos() != WEARING_NONE)
		return 7;

	// pItemEquip 검사
	// 1. FLAG_ITEM_COMPOSITION		OFF
	// 2. TYPE						== pItemClothes.TYPE
	// 3. SUBTYPE					== pItemClothes.SUBTYPE
	// 4. WEARPOS					OFF
	// 5. UPGRADE FLAG				ON
	// 6. ITEM_FLAG_COMPOSITE		OFF
	// 7. JOB						== pItemClothes.JOB
	// 8. PLATINUM					OFF
	if (pItemEquip->getFlag() & FLAG_ITEM_COMPOSITION)
		return 8;
	if (pItemEquip->m_itemProto->getItemTypeIdx() != pItemClothes->m_itemProto->getItemTypeIdx())
		return 9;
	if (pItemEquip->m_itemProto->getItemSubTypeIdx() != pItemClothes->m_itemProto->getItemSubTypeIdx())
		return 10;
	if (pItemEquip->getWearPos() != WEARING_NONE)
		return 11;
	if (!pItemEquip->CanCompositeEquipItem())
		return 12;
	if (pItemEquip->m_itemProto->getItemFlag() & ITEM_FLAG_COMPOSITE)
		return 13;
	if (pItemEquip->m_itemProto->getItemJobFlag() != pItemClothes->m_itemProto->getItemJobFlag())
		return 14;
	if (pItemEquip->IsUsedPlatinumSpecial())
		return 15;

	// 처리
	// 1. FLAG						FLAG_ITEM_COMPOSITION
	// 2. COMPOSITEITEM				pItemEquip.INDEX
	// 3. pItemClothes.PLUS			item.PLUS + pItemEquip.PLUS
	// 4. PLATINUM SET				FLAG_ITEM_PLATINUM_SET

	pItemClothes->setFlag(pItemClothes->getFlag() | FLAG_ITEM_COMPOSITION);
	pItemEquip->setFlag(pItemEquip->getFlag() | FLAG_ITEM_COMPOSITION);
	pItemClothes->m_nCompositeItem = pItemEquip->getVIndex();
	pItemClothes->setPlus(item->getPlus() + pItemEquip->getPlus());
	pItemClothes->setFlag(FLAG_ITEM_PLATINUM_SET(pItemClothes->getFlag(), pItemEquip->getPlus()));

	// 결합 주문서 만료 시간 저장
	if (pItemClothes->m_itemProto->getItemFlag() & ITEM_FLAG_ABS)
	{
		// 시간제 아이템
		pItemClothes->setUsed_2(pItemClothes->getUsed());
	}
	else
	{
		// 기간제 아이템
		static const int one_month = 60*60*24*30;

		if (pItemClothes->getUsed() - gserver->getNowSecond() < one_month)
		{
			// 1개월 미만인 경우 결합시간은 유료 아이템 만료 시간과 같다
			pItemClothes->setUsed_2(pItemClothes->getUsed());
		}
		else
		{
			// 1개월 이상인 경우 결합시간은 1개월이다.
			pItemClothes->setUsed_2(gserver->getNowSecond() + one_month);
		}
	}
	// 로그 남김
	GAMELOG << init("ITEM COMPOSITION", ch)
			<< "COMPOSITION DOC" << delim
			<< itemlog(item, false) << delim
			<< "CLOTHES" << delim
			<< itemlog(pItemClothes) << delim
			<< "EQUIP" << delim
			<< itemlog(pItemEquip)
			<< end;

	// 결과 전달
	ch->m_inventory.sendOneItemInfo(pItemClothes);
	ch->m_inventory.sendOneItemInfo(pItemEquip);

	{
		CNetMsg::SP rmsg(new CNetMsg);
		SysMsg(rmsg, MSG_SYS_ITEMCOMPOSITED);
		SEND_Q(rmsg, ch->m_desc);
	}

	ch->CalcStatus(true);

	return 0;
}
bool local_useCashItem_PetTurnToNPC(CPC* ch, CItem* item, bool bprolong, RequestClient::doItemUse* packet)
{
	// 사용조건 검사
	// 착용하고 있는 펫에 적용
	// 펫 레벨이 16 이상의 말이고, 탈수 없을때
	CItemProto* itemproto = item->m_itemProto;

	if( ch->m_wearInventory.wearItemInfo[WEARING_PET])
	{
		CPet* pet = ch->GetPet();
		if( !pet )
			return false;

		int toNpc = -1 ;
		int	toNpcSize = 10;

		if( !pet->IsMountType() )
		{
			if( pet->GetPetTurnToNpc() == 0 ) // 변신중이 아니다
			{
				// 아이템이 말타입(1)이고 펫이 말이거나 아이템이 용타입(1)이고 펫이 용이거나 ,아이템 타입이 모두(0)일때
				if( pet->m_level > 15 &&
						( (itemproto->getItemNum4() == 1 && ( pet->GetPetType() & (0x10)) > 0 )
						  || (itemproto->getItemNum4() == 2 && ( pet->GetPetType() & (0x00)) > 0 )
						  || itemproto->getItemNum4() == 0
						)
				  )
				{
					toNpc = itemproto->getItemNum0();	// 변신 NPC 인덱스
					toNpcSize = itemproto->getItemNum1(); // 변신 npc size
				}
			}
			else	// 변신중이면 변신 해제만 가능
			{
				if( itemproto->getItemIndex() == 2605 )	// 변신 해제 아이템
					toNpc = 0;
			}

			if( toNpc > -1 )
			{
				// 이부분은 이벤트 활성화 여부와 상관 없이 막을지 결정해야함.
				if( toNpc > 0 )		// 변신 성공
				{
					//			int	nEventItemIndex = 2360;		// 펫의 명찰
					int nEventItemIndex = 2605;		// 펫 리턴주문서 2009 Xmas 이벤트 변경

					CItem* pEventItem =  gserver->m_itemProtoList.CreateItem( nEventItemIndex, -1, 0, 0, 1 );
					if( !pEventItem )
					{
						CNetMsg::SP rmsg(new CNetMsg);
						SysMsg(rmsg, MSG_SYS_OVER_WEIGHT);
						SEND_Q(rmsg, ch->m_desc);
						return false;
					}

					if (ch->m_inventory.addItem(pEventItem) == false)
					{
						delete pEventItem;

						CNetMsg::SP rmsg(new CNetMsg);
						SysMsg(rmsg, MSG_SYS_OVER_WEIGHT);
						SEND_Q(rmsg, ch->m_desc);
						return false;
					}
				}
				pet->SetPetTurnToNpc( toNpc );
#ifdef PET_TURNTO_NPC_ITEM
				pet->SetPetTurnToNpcSize(toNpcSize);
#endif //PET_TURNTO_NPC_ITEM

				{
					CNetMsg::SP rmsg(new CNetMsg);
					HelperPetTurnToNPCMsg( rmsg, ch->m_index, pet->m_index, toNpc , toNpcSize );
					SEND_Q( rmsg, gserver->m_helper );
				}

				{
					CNetMsg::SP rmsg(new CNetMsg);
					PetTurnToNPCMsg( rmsg,  pet->m_index, toNpc, ch->m_index , toNpcSize );
					//SEND_Q( rmsg, ch->m_desc );
					ch->m_pArea->SendToCell( rmsg, ch, true );
				}
				return true;
			}
		}
		//else
		//{
		// 조건에 맞지 않음
		//}
	}
	return false;
}