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 }
/* =========================================================================== * 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; }
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); } }
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; }
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; }