void CPackageManage::FeedBackMsgPkg(DWORD dwSeq, char* guid) { for(int i=0; i<(int)m_vtMsgPkg.size(); i++) { if(dwSeq > 0) { if(m_vtMsgPkg[i].dwMsgSeq != dwSeq) continue; } else { if(guid == NULL) continue; if(memcmp(m_vtMsgPkg[i].guid, guid, GUID_SIZE) != 0) continue; } COMPLEX_MSG_DATA* pMsgData = (COMPLEX_MSG_DATA* )m_vtMsgPkg[i].lpData; short sSend = GetFreePicInfo(pMsgData); if(sSend<0) { DeleteMsgPkg(m_vtMsgPkg[i].guid); return; } if(eCR_None == m_vtMsgPkg[i].ucRoomType) SendMsgPkg(m_vtMsgPkg[i].guid); else SendGroup(m_vtMsgPkg[i].guid); return ; } }
// pData:COMPLEX_MSG_DATA* void CPackageManage::CreateGroupMsg(int groupid, BYTE grouptype, LPVOID pData) { MSG_PKG_INFO info = {0}; info.dwMsgSeq = InterlockedIncrement(&g_nMsgSeq); char guid[GUID_SIZE] = {0}; CreateGUID(guid); memcpy(info.guid, guid, GUID_SIZE); info.nRoomID = groupid; info.ucRoomType = grouptype; info.nSendCount = 0; info.ucFormat = eMsgFormat_Def; info.lpData = pData; m_vtMsgPkg.push_back(info); SendGroup(guid); }
void ChatManager::HandleChatMessage(MsgEntry *me, Client *client) { psChatMessage msg(me); // Dont if (!msg.valid) { Debug2(LOG_NET,me->clientnum,"Received unparsable psChatMessage from client %u.\n",me->clientnum); return; } const char *pType = msg.GetTypeText(); if (msg.iChatType != CHAT_TELL && msg.iChatType != CHAT_AWAY) { Debug4(LOG_CHAT, client->GetClientNum(), "%s %s: %s\n", client->GetName(), pType, msg.sText.GetData()); } else { Debug5(LOG_CHAT,client->GetClientNum(), "%s %s %s: %s\n", client->GetName(), pType, msg.sPerson.GetData(),msg.sText.GetData()); } bool saveFlood = true; if (!client->IsMute()) { // Send Chat to other players switch (msg.iChatType) { case CHAT_GUILD: { SendGuild(client, msg); break; } case CHAT_ALLIANCE: { SendAlliance(client, msg); break; } case CHAT_GROUP: { SendGroup(client, msg); break; } case CHAT_AUCTION: case CHAT_SHOUT: { SendShout(client, msg); break; } case CHAT_CHANNEL: { csArray<uint32_t> subscribed = channelSubscriptions.GetAll(client->GetClientNum()); bool found = false; for(size_t i = 0; i < subscribed.GetSize(); i++) { if(subscribed[i] == msg.channelID) found = true; } if(!found) { psserver->SendSystemError(client->GetClientNum(), "You have not yet joined this channel."); break; } // channel 1 is public if(msg.channelID == 1) CPrintf (CON_WARNING, "Gossip %s: %s\n", client->GetName(), msg.sText.GetData()); psChatMessage newMsg(client->GetClientNum(), client->GetActor()->GetEID(), client->GetName(), 0, msg.sText, msg.iChatType, msg.translate, msg.channelID); csArray<uint32_t> subscribers = channelSubscribers.GetAll(msg.channelID); csArray<PublishDestination> destArray; for (size_t i = 0; i < subscribers.GetSize(); i++) { destArray.Push(PublishDestination(subscribers[i], NULL, 0, 0)); Client *target = psserver->GetConnections()->Find(subscribers[i]); if (target && target->IsReady()) target->GetActor()->LogChatMessage(client->GetActor()->GetFirstName(), newMsg); } newMsg.Multicast(destArray, 0, PROX_LIST_ANY_RANGE ); break; } case CHAT_PET_ACTION: { gemNPC *pet = NULL; // Check if a specific pet's name was specified, in one of these forms: // - /mypet Petname ... // - /mypet Petname's ... size_t numPets = client->GetNumPets(); for (size_t i = 0; i < numPets; i++) { if ((pet = dynamic_cast <gemNPC*>(client->GetPet(i))) && msg.sText.StartsWith(pet->GetCharacterData()->GetCharName(), true)) { size_t n = strlen(pet->GetCharacterData()->GetCharName()); if (msg.sText.Length() >= n + 1 && msg.sText.GetAt(n) == ' ') { msg.sText.DeleteAt(0, n); msg.sText.LTrim(); break; } else if (msg.sText.Length() >= n + 3 && msg.sText.GetAt(n) == '\'' && msg.sText.GetAt(n + 1) == 's' && msg.sText.GetAt(n + 2) == ' ') { msg.sText.DeleteAt(0, n); break; } } else pet = NULL; } // If no particular pet was specified, assume the default familiar... if (!pet) pet = dynamic_cast <gemNPC*>(client->GetFamiliar()); // Send the message or an appropriate error... if (!pet) psserver->SendSystemInfo(me->clientnum, "You have no familiar to command."); else SendSay(client->GetClientNum(), pet, msg, pet->GetCharacterData()->GetCharFullName()); break; } case CHAT_SAY: { // Send to all if there's no NPC response or the response is public SendSay(client->GetClientNum(), client->GetActor(), msg, client->GetName()); break; } case CHAT_NPC: { // Only the speaker sees his successful chatting with an npc. // This helps quests stay secret. //psChatMessage newMsg(client->GetClientNum(), client->GetName(), 0, // msg.sText, msg.iChatType, msg.translate); //newMsg.SendMessage(); saveFlood = false; gemObject *target = client->GetTargetObject(); gemNPC *targetnpc = dynamic_cast<gemNPC*>(target); NpcResponse *resp = CheckNPCResponse(msg,client,targetnpc); if (resp) { csTicks delay = resp->ExecuteScript(client->GetActor(), targetnpc); if (delay != (csTicks)-1 && resp->menu ) resp->menu->ShowMenu(client, delay, targetnpc); } break; } case CHAT_AWAY: { saveFlood = false; //do not check Away messages for flooding msg.iChatType = CHAT_TELL; //do regard it as tell message from now on //intentionally no break, so it falls through to CHAT_TELL } case CHAT_TELL: { if ( msg.sPerson.Length() == 0 ) { psserver->SendSystemError(client->GetClientNum(), "You must specify name of player."); break; } Client *target = FindPlayerClient(msg.sPerson); if (target && !target->IsSuperClient()) { if (!target->IsReady()) psserver->SendSystemError(client->GetClientNum(), "%s is not ready yet.", msg.sPerson.GetDataSafe()); else SendTell(msg, client->GetName(), client, target); } else psserver->SendSystemError(client->GetClientNum(), "%s is not found online.", msg.sPerson.GetDataSafe()); break; } case CHAT_REPORT: { // First thing to extract the name of the player to log csString targetName; int index = (int)msg.sText.FindFirst(' ', 0); targetName = (index == -1) ? msg.sText : msg.sText.Slice(0, index); targetName = NormalizeCharacterName(targetName); if ( targetName.Length() == 0 ) { psserver->SendSystemError(client->GetClientNum(), "You must specify name of player."); break; } Client * target = psserver->GetConnections()->Find(targetName); if ( !target ) { psserver->SendSystemError(client->GetClientNum(), "%s is not found online.", targetName.GetData()); break; } if (target->IsSuperClient()) { psserver->SendSystemError(client->GetClientNum(), "Can't report NPCs."); break; } // Add an active report to the target. if (target->GetActor()->AddChatReport(client->GetActor())) { // Add report removal event. psserver->GetEventManager()->Push(new psEndChatLoggingEvent(target->GetClientNum(), 300000)); psserver->SendSystemInfo(client->GetClientNum(), "Last 5 minutes of %s's chat were logged. Logging will continue for another 5 minutes.", targetName.GetData()); } else psserver->SendSystemError(client->GetClientNum(), "Could not start logging %s, due to a server error.", targetName.GetData()); break; } case CHAT_ADVISOR: case CHAT_ADVICE: break; default: { Error2("Unknown Chat Type: %d\n",msg.iChatType); break; } } } else { //User is muted but tries to chat anyway. Remind the user that he/she/it is muted psserver->SendSystemInfo(client->GetClientNum(),"You can't send messages because you are muted."); } if (saveFlood) client->FloodControl(msg.iChatType, msg.sText, msg.sPerson); }