void CUser::GetUserInfo(Packet & pkt) { CKnights *pKnights = NULL; pkt.SByte(); pkt << GetName() << uint16(GetNation()) << GetClanID() << getFame(); pKnights = g_pMain->GetClanPtr(GetClanID()); if (pKnights == NULL) { pkt << uint32(0) << uint16(0) << uint8(0) << uint16(-1) << uint32(0) << uint8(0); } else { pkt << uint16(pKnights->m_sAlliance) << pKnights->m_strName << pKnights->m_byGrade << pKnights->m_byRanking << uint16(pKnights->m_sMarkVersion) // symbol/mark version << uint16(pKnights->m_sCape) // cape ID << pKnights->m_bCapeR << pKnights->m_bCapeG << pKnights->m_bCapeB << uint8(0) // this is stored in 4 bytes after all. // not sure what this is, but it (just?) enables the clan symbol on the cape // value in dump was 9, but everything tested seems to behave as equally well... // we'll probably have to implement logic to respect requirements. << uint8(1); } pkt << GetLevel() << m_bRace << m_sClass << GetSPosX() << GetSPosZ() << GetSPosY() << m_bFace << m_nHair << m_bResHpType << uint32(m_bAbnormalType) << m_bNeedParty << m_bAuthority << m_bPartyLeader // is party leader (bool) << m_bInvisibilityType // visibility state << uint8(0) // team colour (i.e. in soccer, 0=none, 1=blue, 2=red) << m_bIsHidingHelmet // either this is correct and items are super buggy, or it causes baldness. You choose. << m_sDirection // direction << m_bIsChicken // chicken/beginner flag << m_bRank // king flag << m_bPersonalRank << m_bKnightsRank // NP ranks (total, monthly) << m_sItemArray[BREAST].nNum << m_sItemArray[BREAST].sDuration << uint8(0) << m_sItemArray[LEG].nNum << m_sItemArray[LEG].sDuration << uint8(0) << m_sItemArray[HEAD].nNum << m_sItemArray[HEAD].sDuration << uint8(0) << m_sItemArray[GLOVE].nNum << m_sItemArray[GLOVE].sDuration << uint8(0) << m_sItemArray[FOOT].nNum << m_sItemArray[FOOT].sDuration << uint8(0) << m_sItemArray[SHOULDER].nNum << m_sItemArray[SHOULDER].sDuration << uint8(0) << m_sItemArray[RIGHTHAND].nNum << m_sItemArray[RIGHTHAND].sDuration << uint8(0) << m_sItemArray[LEFTHAND].nNum << m_sItemArray[LEFTHAND].sDuration << uint8(0) << m_sItemArray[CWING].nNum << m_sItemArray[CWING].sDuration << uint8(0) << m_sItemArray[CTOP].nNum << m_sItemArray[CTOP].sDuration << uint8(0) << m_sItemArray[CHELMET].nNum << m_sItemArray[CHELMET].sDuration << uint8(0) << m_sItemArray[CRIGHT].nNum << m_sItemArray[CRIGHT].sDuration << uint8(0) << m_sItemArray[CLEFT].nNum << m_sItemArray[CLEFT].sDuration << uint8(0) << GetZoneID() << uint8(-1) << uint8(-1) << uint16(0) << uint16(0) << uint16(0); }
void CUser::Chat(Packet & pkt) { Packet result; uint16 sessID; uint8 type = pkt.read<uint8>(), bNation; string chatstr, finalstr, strSender, * strMessage; bool isAnnouncement = false; if (isMuted()) return; pkt >> chatstr; if (chatstr.empty() || chatstr.size() > 128) return; // Process GM commands if (isGM() && ProcessChatCommand(chatstr)) return; #if 0 // Removed this - all it seems to do is cause chat to break for GMs (is it 19xx+ only?) if( isGM() && type == GENERAL_CHAT) type = 0x14; #endif // Handle GM notice & announcement commands if (type == PUBLIC_CHAT || type == ANNOUNCEMENT_CHAT) { // Trying to use a GM command without authorisation? Bad player! if (!isGM()) return; if (type == ANNOUNCEMENT_CHAT) type = WAR_SYSTEM_CHAT; // This is horrible, but we'll live with it for now. // Pull the notice string (#### NOTICE : %s ####) from the database. // Format the chat string around it, so our chat data is within the notice g_pMain->GetServerResource(IDP_ANNOUNCEMENT, &finalstr, chatstr.c_str()); isAnnouncement = true; } if (isAnnouncement) { // GM notice/announcements show no name, so don't bother setting it. strMessage = &finalstr; // use the formatted message from the user bNation = KARUS; // arbitrary nation sessID = -1; } else { strMessage = &chatstr; // use the raw message from the user strSender = GetName(); // everything else uses a name, so set it bNation = GetNation(); sessID = GetSocketID(); } ChatPacket::Construct(&result, type, strMessage, &strSender, bNation, sessID); switch (type) { case GENERAL_CHAT: g_pMain->Send_NearRegion(&result, GetMap(), GetRegionX(), GetRegionZ(), GetX(), GetZ()); break; case PRIVATE_CHAT: { CUser *pUser = g_pMain->GetUserPtr(m_sPrivateChatUser); if (pUser != NULL) pUser->Send(&result); } break; case PARTY_CHAT: if (isInParty()) g_pMain->Send_PartyMember(m_sPartyIndex, &result); break; case SHOUT_CHAT: if (m_sMp < (m_iMaxMp / 5)) break; // Characters under level 35 require 3,000 coins to shout. if (!isGM() && GetLevel() < 35 && !GoldLose(SHOUT_COIN_REQUIREMENT)) break; MSpChange(-(m_iMaxMp / 5)); SendToRegion(&result); break; case KNIGHTS_CHAT: if (isInClan()) g_pMain->Send_KnightsMember(GetClanID(), &result); break; case PUBLIC_CHAT: case ANNOUNCEMENT_CHAT: if (isGM()) g_pMain->Send_All(&result); break; case COMMAND_CHAT: if (getFame() == COMMAND_CAPTAIN) g_pMain->Send_CommandChat(&result, m_bNation, this); break; case MERCHANT_CHAT: if (isMerchanting()) SendToRegion(&result); break; case ALLIANCE_CHAT: if (isInClan()) { CKnights *pKnights = g_pMain->GetClanPtr(GetClanID()); if (pKnights != NULL && pKnights->m_sAlliance > 0) g_pMain->Send_KnightsAlliance(pKnights->m_sAlliance, &result); } break; case WAR_SYSTEM_CHAT: if (isGM()) g_pMain->Send_All(&result); break; } }
void Player::save(){ char sql[10000]; sprintf_s(sql, 10000, "update keymap set "); for(int i=0; i<90; i++){ char temp[100]; if(i!=89) sprintf_s(temp, 100, "pos%d=%d, ", i, keys[i]); else sprintf_s(temp, 100, "pos%d=%d where charid=%d; ", i, keys[i], getPlayerid()); strcat_s(sql, 10000, temp); } MySQL::insert(sql); sprintf_s(sql, 10000, "update characters set level=%d, job=%d, str=%d, dex=%d, intt=%d, luk=%d, chp=%d, mhp=%d, cmp=%d, mmp=%d, ap=%d, sp=%d, exp=%d, fame=%d, map=%d, gender=%d, skin=%d, eyes=%d, hair=%d, mesos=%d where id=%d", getLevel(), getJob(), getStr(), getDex(), getInt(), getLuk(), getHP(), getRMHP(), getMP(), getRMMP(), getAp(), getSp(), getExp(), getFame(), getMap(), getGender(), getSkin(), getEyes(), getHair(), inv->getMesos() ,getPlayerid()); MySQL::insert(sql); char temp[1000]; sprintf_s(sql, 10000, "delete from equip where charid=%d;", getPlayerid()); MySQL::insert(sql); bool firstrun = true; for(int i=0; i<inv->getEquipNum(); i++){ if(firstrun == true){ sprintf_s(sql, 10000, "INSERT INTO equip VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", inv->getEquip(i)->id, Drops::equips[inv->getEquip(i)->id].type ,getPlayerid(), inv->getEquipPos(i), inv->getEquip(i)->slots, inv->getEquip(i)->scrolls, inv->getEquip(i)->istr, inv->getEquip(i)->idex, inv->getEquip(i)->iint, inv->getEquip(i)->iluk, inv->getEquip(i)->ihp, inv->getEquip(i)->imp, inv->getEquip(i)->iwatk, inv->getEquip(i)->imatk, inv->getEquip(i)->iwdef, inv->getEquip(i)->imdef, inv->getEquip(i)->iacc, inv->getEquip(i)->iavo, inv->getEquip(i)->ihand, inv->getEquip(i)->ijump, inv->getEquip(i)->ispeed); firstrun = false; } else{ sprintf_s(temp, 1000, ",(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", inv->getEquip(i)->id, Drops::equips[inv->getEquip(i)->id].type ,getPlayerid(), inv->getEquipPos(i), inv->getEquip(i)->slots, inv->getEquip(i)->scrolls, inv->getEquip(i)->istr, inv->getEquip(i)->idex, inv->getEquip(i)->iint, inv->getEquip(i)->iluk, inv->getEquip(i)->ihp, inv->getEquip(i)->imp, inv->getEquip(i)->iwatk, inv->getEquip(i)->imatk, inv->getEquip(i)->iwdef, inv->getEquip(i)->imdef, inv->getEquip(i)->iacc, inv->getEquip(i)->iavo, inv->getEquip(i)->ihand, inv->getEquip(i)->ijump, inv->getEquip(i)->ispeed); strcat_s(sql, 10000, temp); } } MySQL::insert(sql); sprintf_s(sql, 10000, "delete from skills where charid=%d;", getPlayerid()); MySQL::insert(sql); firstrun = true; for(int i=0; i<skills->getSkillsNum(); i++){ if(firstrun == true){ sprintf_s(sql, 10000, "INSERT INTO skills VALUES (%d, %d, %d)", getPlayerid(), skills->getSkillID(i), skills->getSkillLevel(skills->getSkillID(i))); firstrun = false; } else{ sprintf_s(temp, 1000, ",(%d, %d, %d)", getPlayerid(), skills->getSkillID(i), skills->getSkillLevel(skills->getSkillID(i))); strcat_s(sql, 10000, temp); } } MySQL::insert(sql); sprintf_s(sql, 10000, "DELETE FROM items WHERE charid=%d;", getPlayerid()); MySQL::insert(sql); firstrun = true; for(int i=0; i<inv->getItemNum(); i++){ if(firstrun == true){ sprintf_s(sql, 10000, "INSERT INTO items VALUES (%d, %d, %d, %d, %d)", inv->getItem(i)->id, getPlayerid() ,inv->getItem(i)->inv, inv->getItem(i)->pos, inv->getItem(i)->amount); firstrun = false; } else{ sprintf_s(temp, 1000, ",(%d, %d, %d, %d, %d)", inv->getItem(i)->id, getPlayerid() ,inv->getItem(i)->inv, inv->getItem(i)->pos, inv->getItem(i)->amount); strcat_s(sql, 10000, temp); } } MySQL::insert(sql); }
void CUser::SelectCharacter(Packet & pkt) { Packet result(WIZ_SEL_CHAR); uint8 bResult, bInit; if (isBanned()) { Disconnect(); return; } pkt >> bResult >> bInit; result << bResult; if (bResult == 0 || !GetZoneID()) goto fail_return; m_pMap = g_pMain->GetZoneByID(GetZoneID()); if (GetMap() == NULL) goto fail_return; // Temporarily convert the old quest storage format to the new one. // This won't be necessary when Aujard's out of the picture. m_questMap.clear(); for (int i = 0, index = 0; i < m_pUserData->m_sQuestCount; i++) { uint16 sQuestID = GetShort(m_pUserData->m_bstrQuest, index); uint8 bQuestState = GetByte(m_pUserData->m_bstrQuest, index); m_questMap.insert(std::make_pair(sQuestID, bQuestState)); } if (g_pMain->m_nServerNo != GetMap()->m_nServerNo) { _ZONE_SERVERINFO *pInfo = g_pMain->m_ServerArray.GetData(GetMap()->m_nServerNo); if (pInfo == NULL) goto fail_return; SendServerChange(pInfo->strServerIP, bInit); return; } if (g_pMain->m_byBattleOpen == NO_BATTLE && getFame() == COMMAND_CAPTAIN) m_pUserData->m_bFame = CHIEF; if ((GetZoneID() != GetNation() && GetZoneID() < 3 && !g_pMain->m_byBattleOpen) || (GetZoneID() == ZONE_BATTLE && (g_pMain->m_byBattleOpen != NATION_BATTLE)) || (GetZoneID() == ZONE_SNOW_BATTLE && (g_pMain->m_byBattleOpen != SNOW_BATTLE)) || (GetZoneID() == ZONE_FRONTIER && g_pMain->m_byBattleOpen)) { NativeZoneReturn(); Disconnect(); return; } SetLogInInfoToDB(bInit); result << GetZoneID() << GetSPosX() << GetSPosZ() << GetSPosY() << g_pMain->m_byOldVictory; m_bSelectedCharacter = true; Send(&result); SetSlotItemValue(); SetUserAbility(false); if (GetLevel() > MAX_LEVEL) { Disconnect(); return; } m_iMaxExp = g_pMain->GetExpByLevel(GetLevel()); SetRegion(GetNewRegionX(), GetNewRegionZ()); if (GetClanID() == -1) { SetClanID(0); m_pUserData->m_bFame = 0; return; } else if (GetClanID() != 0) { CKnights* pKnights = g_pMain->GetClanPtr( GetClanID() ); if (pKnights != NULL) { g_pMain->m_KnightsManager.SetKnightsUser( GetClanID(), m_pUserData->m_id ); } else if (GetZoneID() > 2) { result.Initialize(WIZ_KNIGHTS_PROCESS); result << uint8(KNIGHTS_LIST_REQ) << GetClanID(); g_pMain->m_LoggerSendQueue.PutData(&result, GetSocketID()); } } return; fail_return: Send(&result); }
void CUser::Chat(Packet & pkt) { Packet result(WIZ_CHAT); uint8 type = pkt.read<uint8>(); char finalstr[1024] = ""; std::string buff, chatstr; bool isAnnouncement = false; if (isMuted()) return; pkt >> chatstr; if (chatstr.empty() || chatstr.size() > 128) return; // Process GM commands if (isGM() && ProcessChatCommand(chatstr)) return; #if 0 // Removed this - all it seems to do is cause chat to break for GMs (is it 19xx+ only?) if( isGM() && type == GENERAL_CHAT) type = 0x14; #endif uint8 bNation = GetNation(); uint16 sessID = GetSocketID(); // Handle GM notice & announcement commands if (type == PUBLIC_CHAT || type == ANNOUNCEMENT_CHAT) { // Trying to use a GM command without authorisation? Bad player! if (!isGM()) return; if (type == ANNOUNCEMENT_CHAT) type = WAR_SYSTEM_CHAT; // This is horrible, but we'll live with it for now. // Pull the notice string (#### NOTICE : %s ####) from the database. CString noticeText = g_pMain->GetServerResource(IDP_ANNOUNCEMENT); // Format the chat string around it, so our chat data is within the notice sprintf_s(finalstr, sizeof(finalstr), noticeText, chatstr.c_str()); bNation = KARUS; // arbitrary nation sessID = -1; isAnnouncement = true; } result.SByte(); result << type << bNation << sessID; if (isAnnouncement) { result << uint8(0); // GM notice/announcements show no name (so specify length of 0) result.DByte(); result << finalstr; // now tack on the formatted message from the user } else { result << m_pUserData.m_id; // everything else provides a name result.DByte(); result << chatstr; // now tack on the chat message from the user } switch (type) { case GENERAL_CHAT: g_pMain->Send_NearRegion(&result, GetMap(), GetRegionX(), GetRegionZ(), GetX(), GetZ()); break; case PRIVATE_CHAT: { if (m_sPrivateChatUser == GetSocketID()) break; CUser *pUser = g_pMain->GetUserPtr(m_sPrivateChatUser); if (pUser != NULL) pUser->Send(&result); } break; case PARTY_CHAT: if (isInParty()) g_pMain->Send_PartyMember(m_sPartyIndex, &result); break; case SHOUT_CHAT: if (m_pUserData.m_sMp < (m_iMaxMp / 5)) break; // Characters under level 35 require 3,000 coins to shout. if (!isGM() && GetLevel() < 35 && !GoldLose(SHOUT_COIN_REQUIREMENT)) break; MSpChange(-(m_iMaxMp / 5)); SendToRegion(&result); break; case KNIGHTS_CHAT: if (isInClan()) g_pMain->Send_KnightsMember(GetClanID(), &result); break; case PUBLIC_CHAT: case ANNOUNCEMENT_CHAT: if (isGM()) g_pMain->Send_All(&result); break; case COMMAND_CHAT: if (getFame() == COMMAND_CAPTAIN) g_pMain->Send_CommandChat(&result, m_pUserData.m_bNation, this); break; case MERCHANT_CHAT: if (isMerchanting()) SendToRegion(&result); break; case WAR_SYSTEM_CHAT: if (isGM()) g_pMain->Send_All(&result); break; } }