diff --git a/source/glest_game/game/chat_manager.cpp b/source/glest_game/game/chat_manager.cpp index 24090d99..3214e7de 100644 --- a/source/glest_game/game/chat_manager.cpp +++ b/source/glest_game/game/chat_manager.cpp @@ -112,7 +112,6 @@ void ChatManager::keyDown(SDL_KeyboardEvent key) { } } - //if(key==vkReturn) { if(isKeyPressed(SDLK_RETURN,key, false) == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym); @@ -158,7 +157,43 @@ void ChatManager::keyDown(SDL_KeyboardEvent key) { } } } - //else if(key==vkBack) { + else if(isKeyPressed(SDLK_TAB,key, false) == true) { + // First find the prefix characters to auto-complete + string autoCompleteName = ""; + if(text.empty() == false) { + int startPos = -1; + for(int i = text.size()-1; i >= 0; --i) { + if(text[i] != ' ') { + startPos = i; + } + else { + break; + } + } + + if(startPos >= 0) { + autoCompleteName = text.substr(startPos); + + // Now lookup the prefix for a match in playernames + string autoCompleteResult = ""; + GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + const GameSettings *settings = gameNetworkInterface->getGameSettings(); + for(unsigned int factionIndex = 0; factionIndex < settings->getFactionCount(); ++factionIndex) { + string playerName = settings->getNetworkPlayerName(factionIndex); + if(playerName.length() > autoCompleteName.length() && + StartsWith(toLower(playerName), toLower(autoCompleteName)) == true) { + autoCompleteResult = playerName.substr(autoCompleteName.length()); + break; + } + } + + if(autoCompleteResult != "") { + WString addText(autoCompleteResult); + appendText(addText.cw_str(), false); + } + } + } + } else if(isKeyPressed(SDLK_BACKSPACE,key,false) == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym); @@ -195,6 +230,34 @@ void ChatManager::switchOnEdit() { textCharLength.clear(); } +void ChatManager::appendText(const wchar_t *addText, bool validateChars) { + for(unsigned int i = 0; i < wcslen(addText); ++i) { + wchar_t key = addText[i]; + if(validateChars == false || isAllowedInputTextKey(key)) { + char buf[4] = {0}; + if (key < 0x80) { + buf[0] = key; + textCharLength.push_back(1); + //printf("1 char, textCharLength = %d\n",textCharLength.size()); + } + else if (key < 0x800) { + buf[0] = (0xC0 | key >> 6); + buf[1] = (0x80 | key & 0x3F); + textCharLength.push_back(2); + //printf("2 char, textCharLength = %d\n",textCharLength.size()); + } + else { + buf[0] = (0xE0 | key >> 12); + buf[1] = (0x80 | key >> 6 & 0x3F); + buf[2] = (0x80 | key & 0x3F); + textCharLength.push_back(3); + //printf("3 char, textCharLength = %d\n",textCharLength.size()); + } + text += buf; + } + } +} + void ChatManager::keyPress(SDL_KeyboardEvent c) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c.keysym.sym,c.keysym.sym); @@ -203,6 +266,11 @@ void ChatManager::keyPress(SDL_KeyboardEvent c) { //space is the first meaningful code // SDLKey key = extractKeyPressed(c); // if(isAllowedInputTextKey(key)) { + + wchar_t key = extractKeyPressedUnicode(c); + wchar_t textAppend[] = { key, 0 }; + appendText(textAppend); +/* wchar_t key = extractKeyPressedUnicode(c); if(isAllowedInputTextKey(key)) { //char szCharText[20]=""; @@ -238,6 +306,7 @@ void ChatManager::keyPress(SDL_KeyboardEvent c) { //delete [] utfStr; } +*/ } } diff --git a/source/glest_game/game/chat_manager.h b/source/glest_game/game/chat_manager.h index 177addef..246f6bb7 100644 --- a/source/glest_game/game/chat_manager.h +++ b/source/glest_game/game/chat_manager.h @@ -50,6 +50,8 @@ private: Font3D *font3D; + void appendText(const wchar_t *addText, bool validateChars=true); + public: ChatManager(); void init(Console* console, int thisTeamIndex, const bool inMenu=false, string manualPlayerNameOverride=""); diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index a5b7e7d0..8823afca 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -311,9 +311,9 @@ void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); // This means no clients are trying to connect at the moment - if(this->getSocket() == NULL) { - checkForNewClients = false; - } + //if(this->getSocket() == NULL) { + // checkForNewClients = false; + //} } //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); } @@ -416,7 +416,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); //send intro message when connected - if(this->getSocket() != NULL) { + if(this->isConnected() == true) { //RandomGen random; //sessionKey = random.randRange(-100000, 100000); srand(time(NULL) / (this->playerIndex + 1)); @@ -427,10 +427,10 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(hasOpenSlots == false) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] !!!!!!!!WARNING - no open slots, disconnecting client\n",__FILE__,__FUNCTION__,__LINE__); - if(this->getSocket() != NULL) { + //if(this->getSocket() != NULL) { NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionSVNString(), getHostName(), playerIndex, nmgstNoSlots, 0, ServerSocket::getFTPServerPort(),""); sendMessage(&networkMessageIntro); - } + //} //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); @@ -439,12 +439,12 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { else { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__,__LINE__); - if(this->getSocket() != NULL) { + //if(this->getSocket() != NULL) { NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionSVNString(), getHostName(), playerIndex, nmgstOk, 0, ServerSocket::getFTPServerPort(),""); sendMessage(&networkMessageIntro); //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - } + //} } } } @@ -455,14 +455,14 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(this->getSocket() != NULL && this->getSocket()->isConnected()) { + if(this->isConnected()) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); this->clearChatInfo(); bool gotTextMsg = true; - for(;this->getSocket() != NULL && this->getSocket()->hasDataToRead() == true && gotTextMsg == true;) { + for(;this->hasDataToRead() == true && gotTextMsg == true;) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] polling for networkMessageType...\n",__FILE__,__FUNCTION__,__LINE__); NetworkMessageType networkMessageType= getNextMessageType(true); @@ -1041,8 +1041,15 @@ void ConnectionSlot::close() { } bool ConnectionSlot::hasValidSocketId() { - bool result = (this->getSocket() != NULL && this->getSocket()->getSocketId() > 0); - return result; + //bool result = (this->getSocket() != NULL && this->getSocket()->getSocketId() > 0); + //return result; + bool result = false; + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + if(socket != NULL && socket->getSocketId() > 0) { + result = true; + } + return result; + } Mutex * ConnectionSlot::getServerSynchAccessor() { @@ -1117,6 +1124,15 @@ bool ConnectionSlot::isConnected() { return result; } +PLATFORM_SOCKET ConnectionSlot::getSocketId() { + PLATFORM_SOCKET result = 0; + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + if(socket != NULL) { + result = socket->getSocketId(); + } + return result; +} + Socket* ConnectionSlot::getSocket() { MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); return socket; @@ -1133,4 +1149,14 @@ void ConnectionSlot::deleteSocket() { socket = NULL; } +bool ConnectionSlot::hasDataToRead() { + bool result = false; + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + + if(socket != NULL && socket->hasDataToRead() == true) { + result = true; + } + return result; +} + }}//end namespace diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 26a7c46c..4836cd3b 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -192,6 +192,8 @@ public: void updateSlot(ConnectionSlotEvent *event); virtual bool isConnected(); + PLATFORM_SOCKET getSocketId(); + protected: Mutex * getServerSynchAccessor(); @@ -201,6 +203,8 @@ protected: void setSocket(Socket *newSocket); void deleteSocket(); virtual void update() {} + + bool hasDataToRead(); }; }}//end namespace diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 20f56bce..d5528803 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -648,9 +648,11 @@ void ServerInterface::updateSocketTriggeredList(std::map & for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; - if(connectionSlot != NULL && connectionSlot->getSocket() != NULL && - connectionSlot->getSocket()->isSocketValid() == true) { - socketTriggeredList[connectionSlot->getSocket()->getSocketId()] = false; + if(connectionSlot != NULL) { + PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); + if(Socket::isSocketValid(&clientSocket) == true) { + socketTriggeredList[clientSocket] = false; + } } } } @@ -659,7 +661,6 @@ void ServerInterface::validateConnectedClients() { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot = slots[i]; - if(connectionSlot != NULL) { connectionSlot->validateConnection(); } @@ -675,8 +676,12 @@ void ServerInterface::signalClientsToRecieveData(std::map ConnectionSlot* connectionSlot = slots[i]; bool socketTriggered = false; - if(connectionSlot != NULL && connectionSlot->getSocket() != NULL) { - socketTriggered = socketTriggeredList[connectionSlot->getSocket()->getSocketId()]; + + if(connectionSlot != NULL) { + PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); + if(Socket::isSocketValid(&clientSocket)) { + socketTriggered = socketTriggeredList[clientSocket]; + } } ConnectionSlotEvent &event = eventList[i]; mapSlotSignalledList[i] = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event); @@ -806,8 +811,9 @@ void ServerInterface::checForLaggingClients(std::map &mapSlotSignalled if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d\n",__FILE__,__FUNCTION__,__LINE__,clientLagExceededOrWarned.first,clientLagExceededOrWarned.second); bool socketTriggered = false; - if(connectionSlot->getSocket() != NULL && connectionSlot->getSocket()->getSocketId() > 0) { - socketTriggered = socketTriggeredList[connectionSlot->getSocket()->getSocketId()]; + PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); + if(clientSocket > 0) { + socketTriggered = socketTriggeredList[clientSocket]; } ConnectionSlotEvent &event = eventList[i]; mapSlotSignalledList[i] = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event); diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index dfab7ad1..4c4fd74f 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -313,9 +313,27 @@ string Ip::getString() const{ # include #endif -static uint32 SockAddrToUint32(struct sockaddr * a) -{ - return ((a)&&(a->sa_family == AF_INET)) ? ntohl(((struct sockaddr_in *)a)->sin_addr.s_addr) : 0; +static uint32 SockAddrToUint32(struct in_addr * a) { + uint32 result = 0; + + //printf("a [%p]\n",a); + if(a != NULL) { + result = ntohl(a->s_addr); + } + + return result; +} + +static uint32 SockAddrToUint32(struct sockaddr * a) { + uint32 result = 0; + + //printf("a [%p] family = %d\n",a,(a ? a->sa_family : -1)); + if(a != NULL && (a->sa_family == AF_INET || a->sa_family == AF_UNSPEC)) { + //result = SockAddrToUint32((((struct sockaddr_in *)a)->sin_addr.s_addr); + result = SockAddrToUint32(&((struct sockaddr_in *)a)->sin_addr); + } + + return result; } // convert a numeric IP address into its string representation @@ -651,12 +669,17 @@ std::vector Socket::getLocalIPAddressList() { if(myhostent) { // get all host IP addresses (Except for loopback) char myhostaddr[101] = ""; - int ipIdx = 0; - while (myhostent->h_addr_list[ipIdx] != 0) { + //int ipIdx = 0; + //while (myhostent->h_addr_list[ipIdx] != 0) { + for(int ipIdx = 0; myhostent->h_addr_list[ipIdx] != NULL; ++ipIdx) { //sprintf(myhostaddr, "%s",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[ipIdx])); - Inet_NtoA(SockAddrToUint32((struct sockaddr *)&myhostent->h_addr_list[ipIdx]), myhostaddr); + //struct sockaddr_in SockAddr; + //memcpy(&(SockAddr.sin_addr),&myhostent->h_addr[ipIdx],myhostent->h_length); + //SockAddr.sin_family = myhostent->h_addrtype; + //Inet_NtoA(SockAddrToUint32((sockaddr *)&SockAddr), myhostaddr); + Inet_NtoA(SockAddrToUint32((struct in_addr *)myhostent->h_addr_list[ipIdx]), myhostaddr); - //printf("%s\n",myhostaddr); + //printf("ipIdx = %d [%s]\n",ipIdx,myhostaddr); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] myhostaddr = [%s]\n",__FILE__,__FUNCTION__,__LINE__,myhostaddr); if(strlen(myhostaddr) > 0 && @@ -664,7 +687,7 @@ std::vector Socket::getLocalIPAddressList() { strncmp(myhostaddr,"0.",2) != 0) { ipList.push_back(myhostaddr); } - ipIdx++; + //ipIdx++; } } @@ -710,7 +733,7 @@ std::vector Socket::getLocalIPAddressList() { struct sockaddr_in *pSockAddr = (struct sockaddr_in *)&ifr.ifr_addr; if(pSockAddr != NULL) { //sprintf(myhostaddr, "%s",inet_ntoa(pSockAddr->sin_addr)); - Inet_NtoA(SockAddrToUint32((struct sockaddr *)&pSockAddr->sin_addr), myhostaddr); + Inet_NtoA(SockAddrToUint32(&pSockAddr->sin_addr), myhostaddr); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] szBuf [%s], myhostaddr = [%s], ifr.ifr_flags = %d, ifrA.ifr_flags = %d, ifr.ifr_name [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf,myhostaddr,ifr.ifr_flags,ifrA.ifr_flags,ifr.ifr_name); // Now only include interfaces that are both UP and running @@ -1794,7 +1817,9 @@ void BroadCastClientSocketThread::execute() { else { //string fromIP = inet_ntoa(bcSender.sin_addr); char szHostFrom[100]=""; - Inet_NtoA(SockAddrToUint32((struct sockaddr *)&bcSender.sin_addr), szHostFrom); + Inet_NtoA(SockAddrToUint32(&bcSender.sin_addr), szHostFrom); + //printf("Client szHostFrom [%s]\n",szHostFrom); + string fromIP = szHostFrom; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"broadcast message received: [%s] from: [%s]\n", buff,fromIP.c_str() ); @@ -2500,6 +2525,8 @@ void BroadCastSocketThread::execute() { std::vector ipSubnetMaskList; for(unsigned int idx = 0; idx < ipList.size() && idx < MAX_NIC_COUNT; idx++) { string broadCastAddress = getNetworkInterfaceBroadcastAddress(ipList[idx]); + //printf("idx = %d broadCastAddress [%s]\n",idx,broadCastAddress.c_str()); + //strcpy(subnetmask[idx], broadCastAddress.c_str()); if(broadCastAddress != "" && std::find(ipSubnetMaskList.begin(),ipSubnetMaskList.end(),broadCastAddress) == ipSubnetMaskList.end()) { ipSubnetMaskList.push_back(broadCastAddress);