/*** * We've been told from another server that someone has joined (or rejected joining) a clan. ***/ void CUdpSocket::RecvJoinKnights(char* pBuf, BYTE command) { int knightsindex = 0, index = 0; char charid[MAX_ID_SIZE+1]; CString clanNotice; knightsindex = GetShort( pBuf, index ); if (!GetKOString(pBuf, charid, index, MAX_ID_SIZE)) return; CKnights *pKnights = g_pMain->GetClanPtr(knightsindex); if (pKnights == NULL) return; if (command == KNIGHTS_JOIN) { clanNotice = g_pMain->GetServerResource(IDS_KNIGHTS_JOIN); pKnights->AddUser(charid); TRACE("UDP - RecvJoinKnights - name=%s, index=%d\n", charid, knightsindex); } else { clanNotice = g_pMain->GetServerResource(IDS_KNIGHTS_WITHDRAW); pKnights->RemoveUser(charid); TRACE("UDP - RecvJoinKnights - name=%s, index=%d\n", charid, knightsindex ); } pKnights->SendChat(clanNotice, charid); }
/*** * We've been told from another server that a clan has been created. ***/ void CUdpSocket::RecvCreateKnights(char* pBuf) { int index = 0, send_index = 0, knightsindex = 0, nation = 0, community = 0; char knightsname[MAX_ID_SIZE+1], chiefname[MAX_ID_SIZE+1]; CKnights* pKnights = NULL; community = GetByte( pBuf, index ); knightsindex = GetShort( pBuf, index ); nation = GetByte( pBuf, index ); if (!GetKOString(pBuf, knightsname, index, MAX_ID_SIZE) || !GetKOString(pBuf, chiefname, index, MAX_ID_SIZE)) return; pKnights = new CKnights(); pKnights->m_sIndex = knightsindex; pKnights->m_byFlag = community; pKnights->m_byNation = nation; strcpy(pKnights->m_strName, knightsname); strcpy(pKnights->m_strChief, chiefname); pKnights->AddUser(chiefname); g_pMain->m_KnightsArray.PutData( pKnights->m_sIndex, pKnights ); //TRACE("UDP - RecvCreateKnights - knname=%s, name=%s, index=%d\n", knightsname, chiefname, knightsindex); }
void CKnightsManager::ReqDestroyKnights(CUser *pUser, Packet & pkt) { uint16 sClanID = pkt.read<uint16>(); CKnights *pKnights = g_pMain->GetClanPtr(sClanID); if (pKnights == nullptr) return; int8 bResult = int8(g_DBAgent.DeleteKnights(sClanID)); pKnights->Disband(pUser); }
/*** * We've been told from another server that the clan is disbanding ***/ void CUdpSocket::RecvDestroyKnights(char* pBuf) { int index = 0; int16 knightsindex = GetShort(pBuf, index); CKnights *pKnights = g_pMain->GetClanPtr(knightsindex); if (pKnights == NULL) { TRACE("UDP - ### RecvDestoryKnights Fail == index = %d ###\n", knightsindex); return; } pKnights->Disband(); }
void CKnightsManager::ReqCreateKnights(CUser *pUser, Packet & pkt) { if (pUser == nullptr) return; Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_CREATE)); string strKnightsName, strChief; uint16 sClanID; uint8 bFlag, bNation; int8 bResult; pkt >> bFlag >> sClanID >> bNation >> strKnightsName >> strChief; bResult = g_DBAgent.CreateKnights(sClanID, bNation, strKnightsName, strChief, bFlag); if (bResult < 0) { result << bResult; pUser->Send(&result); return; } CKnights *pKnights = new CKnights(); pKnights->m_sIndex = sClanID; pKnights->m_byFlag = bFlag; pKnights->m_byNation = bNation; pKnights->m_strName = strKnightsName; pKnights->m_strChief = pUser->GetName(); pUser->GoldLose(CLAN_COIN_REQUIREMENT, false); g_pMain->m_KnightsArray.PutData(pKnights->m_sIndex, pKnights); pKnights->AddUser(pUser); // Ensure the clan leader's fame is set // CKnights::AddUser() will default it to TRAINEE, so it needs to be set afterwards. pUser->m_bFame = CHIEF; result << uint8(1) << pUser->GetSocketID() << sClanID << strKnightsName << pKnights->m_byGrade << pKnights->m_byRanking << pUser->m_iGold; pUser->SendToRegion(&result); }
void CUdpSocket::RecvCreateKnights( char* pBuf ) { int index = 0, send_index = 0, namelen = 0, idlen = 0, knightsindex = 0, nation = 0, community = 0; char knightsname[MAX_ID_SIZE+1]; memset( knightsname, 0x00, MAX_ID_SIZE+1 ); char chiefname[MAX_ID_SIZE+1]; memset( chiefname, 0x00, MAX_ID_SIZE+1 ); CKnights* pKnights = NULL; community = GetByte( pBuf, index ); knightsindex = GetShort( pBuf, index ); nation = GetByte( pBuf, index ); namelen = GetShort( pBuf, index ); GetString( knightsname, pBuf, namelen, index ); idlen = GetShort( pBuf, index ); GetString( chiefname, pBuf, idlen, index ); pKnights = new CKnights; pKnights->InitializeValue(); pKnights->m_sIndex = knightsindex; pKnights->m_byFlag = community; pKnights->m_byNation = nation; strcpy( pKnights->m_strName, knightsname ); strcpy( pKnights->m_strChief, chiefname ); memset( pKnights->m_strViceChief_1, 0x00, MAX_ID_SIZE+1); memset( pKnights->m_strViceChief_2, 0x00, MAX_ID_SIZE+1); memset( pKnights->m_strViceChief_3, 0x00, MAX_ID_SIZE+1); pKnights->m_sMembers = 1; pKnights->m_nMoney = 0; pKnights->m_nPoints = 0; pKnights->m_byGrade = 5; pKnights->m_byRanking = 0; for(int i=0; i<MAX_CLAN; i++) { pKnights->m_arKnightsUser[i].byUsed = 0; strcpy(pKnights->m_arKnightsUser[i].strUserName, ""); } m_pMain->m_KnightsArray.PutData( pKnights->m_sIndex, pKnights ); // 클랜정보에 추가 m_pMain->m_KnightsManager.AddKnightsUser( knightsindex, chiefname ); //TRACE("UDP - RecvCreateKnights - knname=%s, name=%s, index=%d\n", knightsname, chiefname, knightsindex); }
void CKnightsManager::ReqCreateKnights(CUser *pUser, Packet & pkt) { if (pUser == nullptr) return; Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_CREATE)); string strKnightsName, strChief; uint16 sClanID; uint8 bFlag, bNation; int8 bResult; pkt >> bFlag >> sClanID >> bNation >> strKnightsName >> strChief; bResult = g_DBAgent.CreateKnights(sClanID, bNation, strKnightsName, strChief, bFlag); if (bResult < 0) { result << bResult; pUser->Send(&result); return; } CKnights *pKnights = new CKnights(); pKnights->m_sIndex = sClanID; pKnights->m_byFlag = bFlag; pKnights->m_byNation = bNation; pKnights->m_strName = strKnightsName; pKnights->m_strChief = pUser->GetName(); pUser->m_iGold -= CLAN_COIN_REQUIREMENT; pUser->m_bFame = CHIEF; g_pMain->m_KnightsArray.PutData(pKnights->m_sIndex, pKnights); pKnights->AddUser(pUser); result << uint8(1) << pUser->GetSocketID() << sClanID << strKnightsName << pKnights->m_byGrade << pKnights->m_byRanking << pUser->m_iGold; pUser->SendToRegion(&result); }
void CUser::CastleSiegeWarProcess(CUser * pUser) { if (pUser == nullptr || GetClanID() <= 0) return; _KNIGHTS_SIEGE_WARFARE *pKnightSiegeWar = g_pMain->GetSiegeMasterKnightsPtr(1); CKnights * pKnights = g_pMain->GetClanPtr(pUser->m_bKnights); pKnightSiegeWar->sMasterKnights = pKnights->m_sIndex; g_pMain->UpdateSiege(pKnightSiegeWar->sCastleIndex, pKnightSiegeWar->sMasterKnights, pKnightSiegeWar->bySiegeType, pKnightSiegeWar->byWarDay, pKnightSiegeWar->byWarTime, pKnightSiegeWar->byWarMinute); g_pMain->m_KnightsSiegeWarfareArray.GetData(pKnightSiegeWar->sMasterKnights); g_pMain->m_SiegeWarWinKnightsNotice = pKnights->GetName(); g_pMain->Announcement(IDS_NPC_GUIDON_DESTORY); g_pMain->m_byBattleSiegeWarMomument = true; if (pKnightSiegeWar != nullptr) { Packet result(WIZ_SIEGE, uint8(2)); result << pKnights->GetID() << pKnights->m_sMarkVersion; g_pMain->Send_Zone(&result,ZONE_DELOS); } }
void CUser::GetUserInfo(Packet & pkt) { pkt.SByte(); pkt << GetName() << uint16(GetNation()) << GetClanID() << GetFame(); CKnights * pKnights = g_pMain->GetClanPtr(GetClanID()); if (pKnights == nullptr) { pkt << uint32(0) << uint16(0) << uint8(0) << uint16(-1) << uint32(0) << uint8(0); } else { pkt << pKnights->GetAllianceID() << 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); } // There are two event-driven invisibility states; dispel on attack, and dispel on move. // These are handled primarily server-side; from memory the client only cares about value 1 (which we class as 'dispel on move'). // As this is the only place where this flag is actually sent to the client, we'll just convert 'dispel on attack' // back to 'dispel on move' as the client expects. uint8 bInvisibilityType = m_bInvisibilityType; if (bInvisibilityType == INVIS_DISPEL_ON_ATTACK) bInvisibilityType = INVIS_DISPEL_ON_MOVE; 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) << 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 != nullptr) 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 != nullptr && pKnights->isInAlliance()) g_pMain->Send_KnightsAlliance(pKnights->GetAllianceID(), &result); } break; case WAR_SYSTEM_CHAT: if (isGM()) g_pMain->Send_All(&result); break; } }
void CUser::GetUserInfo(Packet & pkt) { pkt.SByte(); pkt << GetName() << GetNation() << GetClanID() << GetFame(); CKnights * pKnights = g_pMain->GetClanPtr(GetClanID()); if (pKnights == nullptr) { //pkt /*<< uint8(0)*/ << uint16(0) << uint8(0) << uint8(0); pkt << uint32(0) << uint16(0) << uint8(0) << uint16(-1); } else { pkt << pKnights->GetAllianceID() << pKnights->m_strName << pKnights->m_byGrade << pKnights->m_byRanking << uint16(pKnights->m_sMarkVersion) // symbol/mark version << pKnights->GetCapeID(pKnights); // cape ID } // There are two event-driven invisibility states; dispel on attack, and dispel on move. // These are handled primarily server-side; from memory the client only cares about value 1 (which we class as 'dispel on move'). // As this is the only place where this flag is actually sent to the client, we'll just convert 'dispel on attack' // back to 'dispel on move' as the client expects. uint8 bInvisibilityType = m_bInvisibilityType; if (bInvisibilityType != INVIS_NONE) bInvisibilityType = INVIS_DISPEL_ON_MOVE; pkt << GetLevel() << m_bRace << m_sClass << GetSPosX() << GetSPosZ() << GetSPosY() << m_bFace << m_nHair << m_bResHpType << uint32(m_bAbnormalType)//uint8(m_bAbnormalType) << m_bNeedParty << m_bAuthority << m_bPartyLeader // is party leader (bool) << bInvisibilityType // visibility state //<< uint8(m_teamColour) // 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_bKnightsRank << m_bPersonalRank; // NP ranks (total, monthly) uint8 equippedItems[] = { BREAST, LEG, HEAD, GLOVE, FOOT, SHOULDER, RIGHTHAND, LEFTHAND, CTOP, CHELMET }; foreach_array(i, equippedItems) { _ITEM_DATA * pItem = GetItem(equippedItems[i]); if (pItem == nullptr) continue; pkt << pItem->nNum << pItem->sDuration << pItem->bFlag; }
/*** * We've been told from another server that a user's status in the clan has changed. ***/ void CUdpSocket::RecvModifyFame(char* pBuf, BYTE command) { CString clanNotice; int index = 0, knightsindex = 0, vicechief = 0; char userid[MAX_ID_SIZE+1]; knightsindex = GetShort(pBuf, index); if (!GetKOString(pBuf, userid, index, MAX_ID_SIZE)) return; CUser *pTUser = g_pMain->GetUserPtr(userid, TYPE_CHARACTER); CKnights *pKnights = g_pMain->GetClanPtr(knightsindex); if (pKnights == NULL) return; switch (command) { case KNIGHTS_REMOVE: case KNIGHTS_REJECT: if (pTUser) { pTUser->SetClanID(0); pTUser->m_pUserData->m_bFame = 0; if (command == KNIGHTS_REMOVE) clanNotice = g_pMain->GetServerResource(IDS_KNIGHTS_REMOVE); } g_pMain->m_KnightsManager.RemoveKnightsUser(knightsindex, userid); break; case KNIGHTS_ADMIT: if (pTUser) pTUser->m_pUserData->m_bFame = KNIGHT; break; case KNIGHTS_CHIEF+0x10: if (pTUser) { pTUser->m_pUserData->m_bFame = CHIEF; clanNotice = g_pMain->GetServerResource(IDS_KNIGHTS_CHIEF); } break; case KNIGHTS_VICECHIEF+0x10: if (pTUser) { pTUser->m_pUserData->m_bFame = VICECHIEF; clanNotice = g_pMain->GetServerResource(IDS_KNIGHTS_VICECHIEF); } break; case KNIGHTS_OFFICER+0x10: if (pTUser) pTUser->m_pUserData->m_bFame = OFFICER; break; case KNIGHTS_PUNISH+0x10: if (pTUser) pTUser->m_pUserData->m_bFame = PUNISH; break; } if (pTUser != NULL) pTUser->SendClanUserStatusUpdate(command == KNIGHTS_REMOVE); if (clanNotice.GetLength() == 0) return; Packet result; // Construct the clan system chat packet pKnights->ConstructChatPacket(result, clanNotice, pTUser != NULL ? pTUser->m_pUserData->m_id : userid); // If we've been removed from a clan, tell the user as well (since they're no longer in the clan) if (command == KNIGHTS_REMOVE && pTUser != NULL) pTUser->Send(&result); // Otherwise, since we're actually in the clan, we don't need to be explicitly told what happened. if (pKnights != NULL) pKnights->Send(&result); }