![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 #include "ChatServer.h" 00002 #include "JoinChannelPacket.h" 00003 #include "ReplyPacket.h" 00004 #include "SendMessageToChannelPacket.h" 00005 00006 #include <limits.h> 00007 00008 namespace SraNetwork { 00009 00010 unsigned int ChatServer::lastUsedClientId = 0; 00011 00012 tbb::concurrent_hash_map<SystemAddress, unsigned int, SystemAddressCompare> ChatServer::m_vChatUserRegister; 00013 tbb::concurrent_hash_map<unsigned int, std::vector<RakString>> ChatServer::m_mPendingUserMessages; 00014 tbb::concurrent_hash_map<unsigned int, std::vector<int>> ChatServer::m_mUserChatGroupMap; 00015 tbb::concurrent_hash_map<unsigned int, std::vector<int>> ChatServer::m_mChatGroupMap; 00016 00017 ChatServer::ChatServer(void) 00018 { 00019 } 00020 00021 ChatServer::~ChatServer(void) 00022 { 00023 } 00024 00025 void ChatServer::ClientConnectionThread() 00026 { 00027 printf("Listening for chat clients ..... \n"); 00028 RakPeerInterface *m_rClientInterface = RakPeerInterface::GetInstance(); 00029 SocketDescriptor chatSocket(SraNetwork::CHAT_CLIENT_PORT, 0); 00030 m_rClientInterface->Startup(2, &chatSocket, 1); 00031 m_rClientInterface->SetMaximumIncomingConnections(2); //2 ? 00032 00033 bool running = true; 00034 while (running) 00035 { 00036 Packet* m_pPacket = m_rClientInterface->Receive(); 00037 if (m_pPacket) 00038 { 00039 if (m_pPacket->data[0] == ID_NEW_INCOMING_CONNECTION) 00040 { 00041 printf("Chat client connected\n"); 00042 } 00043 else 00044 { 00045 // Now for our own packets. 00046 BitStream stream(m_pPacket->data, m_pPacket->length, false); 00047 SraPacket sraPacket; 00048 sraPacket.Deserialize(&stream); 00049 if (sraPacket.opCode == ID_CHAT_CHANNEL_MESSAGE) 00050 { 00051 SendMessageToChannelPacket chatPacket; 00052 chatPacket.Deserialize(&stream); 00053 00054 printf("Client sent a message to channel %d\n", chatPacket.channelId); 00055 00056 // TODO: Maybe we should move this to a separated class, like 00057 // the world server message pump ... 00058 00059 // First we have to check if the channel exists and if the user is in it. 00060 // We will do this by simply checking the user chat group list: 00061 tbb::concurrent_hash_map<SystemAddress, unsigned int, SystemAddressCompare>::const_accessor acc; 00062 unsigned int clientID = -1; 00063 if (m_vChatUserRegister.find(acc, m_pPacket->systemAddress) ) 00064 { 00065 // We already have create an id for this client, so use it 00066 clientID = acc->second; 00067 } else 00068 { 00069 printf("User is not registered, ignoring the message\n"); 00070 } 00071 00072 00073 // Whoa this is ugly and will suck a lot of performance....find a better solution!!! 00074 00075 // Search for the channel: 00076 tbb::concurrent_hash_map<unsigned int, std::vector<int>>::const_accessor userGroupsAcc; 00077 // Get user channel list. 00078 if (m_mUserChatGroupMap.find(userGroupsAcc, clientID)) 00079 { 00080 // now find the channel id : 00081 bool found = false; 00082 for (std::vector<int>::const_iterator vit = userGroupsAcc->second.begin(); vit != userGroupsAcc->second.end(); ++vit) 00083 { 00084 if ( *vit == chatPacket.channelId) 00085 { 00086 printf("Found channel\n"); 00087 found = true; 00088 break; 00089 } 00090 } 00091 if (found) 00092 { 00093 // Ok the user is in this channel, so now send a message to all clients 00094 // that are in this channel: 00095 tbb::concurrent_hash_map<unsigned int, std::vector<int>>::const_accessor chatGroupAcc; 00096 if (m_mChatGroupMap.find(chatGroupAcc, chatPacket.channelId)) 00097 { 00098 // iterate through all ids: 00099 for (std::vector<int>::const_iterator userIt = chatGroupAcc->second.begin(); userIt != chatGroupAcc->second.end(); ++userIt) 00100 { 00101 // ok nooow we have to get the corresponding system address from this index: 00102 int userID = *userIt; 00103 for ( 00104 tbb::concurrent_hash_map<SystemAddress, unsigned int, SystemAddressCompare>::iterator it = m_vChatUserRegister.begin(); 00105 it != m_vChatUserRegister.end(); ++it) 00106 { 00107 if ( it->second == *userIt) 00108 { 00109 printf("Sending the message to a user\n"); 00110 SystemAddress addr = it->first; 00111 addr.SetPortA(CLIENT_CHAT_PORT); 00112 uint32_t sent = 00113 m_rClientInterface->Send(&stream, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, addr, false); 00114 printf("I have sent %d bytes", sent); 00115 // Skip the rest of the entries. 00116 break; 00117 } 00118 } 00119 } 00120 } 00121 } 00122 } 00123 } 00124 } 00125 } 00126 m_rClientInterface->DeallocatePacket(m_pPacket); 00127 Sleep(10); 00128 } 00129 } 00130 00131 void ChatServer::ServerConnectionThread() 00132 { 00133 //Connect to world server 00134 RakPeerInterface *m_rServerInterface = RakPeerInterface::GetInstance(); 00135 SocketDescriptor chatSocket(SraNetwork::CHAT_SERVER_PORT, 0); 00136 m_rServerInterface->Startup(1, &chatSocket, 1); 00137 m_rServerInterface->Connect(SraNetwork::WORLD_SERVER_ADDR, SraNetwork::SERVER_CHAT_PORT, 0, 0, 0); 00138 00139 printf("Connecting to world server\n"); 00140 00141 bool done = false; 00142 bool result = false; //don't return in loop so we can shut down RakNet before exiting 00143 while (!done) //Block while connecing 00144 { 00145 Packet* m_pPacket = m_rServerInterface->Receive(); 00146 if (m_pPacket) 00147 { 00148 if (m_pPacket->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) 00149 { 00150 result = true; 00151 } 00152 else if (m_pPacket->data[0] == ID_CONNECTION_ATTEMPT_FAILED) 00153 { 00154 printf("Failed: connection attempt failed\n"); 00155 } else 00156 { 00157 printf("Failed: Unknown opcode %d\n", m_pPacket->data[0]); 00158 } 00159 m_rServerInterface->DeallocatePacket(m_pPacket); 00160 m_pPacket = 0; 00161 done = true; 00162 } 00163 Sleep(10); 00164 } 00165 if (!result) 00166 { 00167 printf("Failed to connect to world, exiting now\n"); 00168 m_rServerInterface->Shutdown(0); 00169 return; 00170 } 00171 printf("Connection established, waiting for chat connections\n"); 00172 00173 bool running = true; //maybe we do not need this, but i don't like while(1) :P 00174 while (running) 00175 { 00176 Packet* m_pPacket = m_rServerInterface->Receive(); 00177 if (m_pPacket) 00178 { 00179 if ( m_pPacket->data[0] == ID_CONNECTION_LOST ) { 00180 // Do we really need this hard connection to the world? 00181 // we could also run without it. 00182 printf("Lost connection to world server ! Shutting down now\n"); 00183 running = false; 00184 } 00185 else 00186 { 00187 // Now for our own packets. 00188 BitStream stream(m_pPacket->data, m_pPacket->length, false); 00189 SraPacket sraPacket; 00190 sraPacket.Deserialize(&stream); 00191 if (sraPacket.opCode == ID_CHAT_CHANNEL_REGISTER) 00192 { 00193 bool success = true; 00194 JoinChannelPacket joinPacket; 00195 joinPacket.Deserialize(&stream); 00196 00197 printf("Received chat channel registration message for channel %d", joinPacket.channelId); 00198 00199 tbb::concurrent_hash_map<SystemAddress, unsigned int, SystemAddressCompare>::accessor acc; 00200 unsigned int clientID = -1; 00201 if (m_vChatUserRegister.find(acc, joinPacket.clientAddress) ) 00202 { 00203 // We already have create an id for this client, so use it 00204 clientID = acc->second; 00205 } else 00206 { 00207 // Well we coooouuuld check if the modded value 00208 // is already in use, but UINT_MAX is 2^32 wich should be 00209 // large enough to be quite sure this should not happen... 00210 lastUsedClientId = (lastUsedClientId+1)%UINT_MAX; 00211 clientID = lastUsedClientId; 00212 m_vChatUserRegister.insert( acc, joinPacket.clientAddress); 00213 acc->second = clientID; 00214 } 00215 printf("User has clientID %d ", clientID); 00216 // Add requested channel to the users list of channels. 00217 tbb::concurrent_hash_map<unsigned int, std::vector<int>>::accessor userGroupsAcc; 00218 if (m_mUserChatGroupMap.find(userGroupsAcc, joinPacket.channelId)) 00219 { 00220 // if we already have a list for this user, 00221 // so simply add the new channel. 00222 if (userGroupsAcc->second.size() <= MAX_NUMBER_OF_CHAT_GROUPS_PER_USER) 00223 { 00224 printf("Adding channel to user\n"); 00225 userGroupsAcc->second.push_back(joinPacket.channelId); 00226 } 00227 else 00228 { 00229 printf("Error: User exceeded the max number of chat groups!\n"); 00230 success = false; 00231 } 00232 } 00233 else 00234 { 00235 printf("Creating a new group list\n"); 00236 // if not, we need to create a new user list. 00237 std::vector<int> userList; 00238 userList.push_back(joinPacket.channelId); 00239 m_mUserChatGroupMap.insert(userGroupsAcc, clientID); 00240 userGroupsAcc->second = userList; 00241 } 00242 00243 // Now we need to find the channel list the user wants to join 00244 tbb::concurrent_hash_map<unsigned int, std::vector<int>>::accessor chatGroupsAcc; 00245 if (m_mChatGroupMap.find(chatGroupsAcc, joinPacket.channelId)) 00246 { 00247 // if we already the selected channel, 00248 // so simply add the user. 00249 if (chatGroupsAcc->second.size() <= MAX_NUMBER_OF_USERS_PER_GROUP) 00250 { 00251 printf("Adding user to channel\n"); 00252 chatGroupsAcc->second.push_back(clientID); 00253 } 00254 else 00255 { 00256 printf("Error: To many users in chat group\n"); 00257 success = false; 00258 } 00259 } 00260 else 00261 { 00262 if (m_mChatGroupMap.size() <= MAX_NUMBER_OF_CHAT_GROUPS) 00263 { 00264 00265 printf("Creating new chat group\n"); 00266 // if not, we will create a new chat group 00267 std::vector<int> userList; 00268 userList.push_back(clientID); 00269 m_mChatGroupMap.insert(chatGroupsAcc, joinPacket.channelId); 00270 chatGroupsAcc->second = userList; 00271 } 00272 else 00273 { 00274 printf("Error: Max number of chat groups exceeded\n"); 00275 success = false; 00276 } 00277 } 00278 00279 // After the joinig process has completed, we will sent a message 00280 // to the user. Be sure to do this always at the end so a potential 00281 // error will not send a return message. 00282 if (success) 00283 { 00284 printf("Send success message to server/client \n"); 00285 // Send a message to the player that contains our ip 00286 JoinChannelPacket rp; 00287 // This is used to indicate a success message. 00288 rp.channelId = 0; 00289 rp.clientAddress = joinPacket.clientAddress; 00290 // This is kinda ugly: Because we don't have the socket 00291 // to the client, this message has to be sent back to the server 00292 // and forwarded to the client. 00293 BitStream bs; 00294 rp.Serialize(&bs); 00295 m_rServerInterface->Send(&bs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true); 00296 } 00297 } 00298 } 00299 } 00300 m_rServerInterface->DeallocatePacket(m_pPacket); 00301 Sleep(10); 00302 } 00303 } 00304 }
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.