Shadowrun: Awakened 29 September 2011 - Build 871
SraClientConnection.cpp
Go to the documentation of this file.
00001 /*
00002 * SRAClientConnection - The connection between the SRA server and the UDK.
00003 * All those methods may be called from UnrealScript code by using:
00004 *  DLLBind(SraClientConnection);
00005 * 
00006 * @Author Michael Matzen <mim@informatik.uni-kiel.de>
00007 *
00008 * This program is free software; you can redistribute it and/or modify it
00009 * under the terms of the GNU General Public License as published by the Free
00010 * Software Foundation; either version 2 of the License, or (at your option)
00011 * any later version.
00012 *
00013 * This program is distributed in the hope that it will be useful, but WITHOUT
00014 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
00016 * more details.
00017 *
00018 * You should have received a copy of the GNU General Public License along with
00019 * this program; if not, write to the Free Software Foundation, Inc., 51
00020 * Franklin St, Fifth Floor, Boston, MA 02110, USA
00021 * 
00022 */
00023 
00024 #include "stdio.h"
00025 #include "stdlib.h"
00026 #include <vector>
00027 #include "Connectivity.h"
00028 
00029 #include "LoginPacket.h"
00030 #include "LoginReplyPacket.h"
00031 #include "GetClientCharactersPacket.h"
00032 #include "ConnectToServerPacket.h"
00033 #include "GetServerListPacket.h"
00034 #include "ReplyPacket.h"
00035 #include "CreateCharacterPacket.h"
00036 #include "JoinChannelPacket.h"
00037 #include "LeaveChannelPacket.h"
00038 #include "ChatMessage.h"
00039 #include "SendMessageToChannelPacket.h"
00040 
00041 #include "Utils.h"
00042 
00043 
00044 extern "C" 
00045 {
00046     using namespace SraNetwork;
00047     using namespace RakNet;
00048 
00049     struct FString
00050     {
00051         wchar_t* Data;
00052         int ArrayNum;
00053         int ArrayMax;
00054     };
00055 
00056     // Struct for data movement:
00057     struct ServerReplyMessages
00058     {
00059         int resultCode;
00060         FString message;
00061     };
00062 
00063     struct DEBUGServerReplyMessage
00064     {
00065         int resultCode;
00066         wchar_t* message;
00067     };
00068 
00070     static RakNet::RakPeerInterface *m_rServerInterface;
00071 
00073     // TODO: Support multiple chat interfaces.
00074     static RakNet::RakPeerInterface *m_rChatServerInterface;
00075 
00077     static int myPID = -1;
00079     static int myCharID = -1;
00081     static RakNet::PublicKey publicKey;
00082 
00086     __declspec(dllexport) bool SraConnectToServer(const wchar_t* serverAddress)
00087     {
00088         printf("Start connecting\n");
00089         //Load public key:
00090     /*  char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
00091         FILE* fp;
00092         fopen_s(&fp, "sra_public.key","r");
00093         if (!fp) 
00094         {
00095             printf("Public key not found!\n");
00096             return false;
00097         }
00098         fread(public_key, sizeof(public_key), 1, fp);
00099         fclose(fp);
00100         publicKey.publicKey = public_key;
00101         publicKey.publicKeyMode = RakNet::PKM_USE_KNOWN_PUBLIC_KEY;
00102 */
00103         //Do not connect when the interface is already connected
00104         if (m_rServerInterface && m_rServerInterface->NumberOfConnections() > 0) 
00105         {
00106             printf("Already connected!\n");
00107             return true;
00108         }
00109         //Start connecting
00110         m_rServerInterface = RakNet::RakPeerInterface::GetInstance();
00111         RakNet::SocketDescriptor serverSocket(SraNetwork::CLIENT_SERVER_PORT, 0);
00112         m_rServerInterface->Startup(1, &serverSocket, 1);
00113         //Convert wchar_t* -> char*
00114         char *saddr = new char[wcslen(serverAddress)+1];
00115         size_t res=0;
00116         wcstombs_s( &res, saddr, strlen(saddr), (const wchar_t*)serverAddress, strlen(saddr));
00117         //wcstombs(saddr, serverAddress, wcslen(serverAddress));
00118 
00119         printf("Connecting to world server @ %s\n", saddr);
00120         RakNet::ConnectionAttemptResult result = 
00121             m_rServerInterface->Connect(SraNetwork::WORLD_SERVER_ADDR, SraNetwork::SERVER_CLIENT_PORT, 0, 0, &publicKey);
00122 
00123         // Only check if the connection attempt was succesfull, everything else will be handled by poll()
00124         if (result != RakNet::ConnectionAttemptResult::CONNECTION_ATTEMPT_STARTED)
00125         {
00126             return false;
00127         }
00128         return true;
00129     }
00130 
00134     __declspec(dllexport) bool SraConnectToChatServer(const wchar_t* serverAddress)
00135     {
00136         //Load public key:
00137     /*  char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES];
00138         FILE* fp;
00139         fopen_s(&fp, "sra_public.key","r");
00140         if (!fp) 
00141         {
00142             printf("Public key not found!\n");
00143             return false;
00144         }
00145         fread(public_key, sizeof(public_key), 1, fp);
00146         fclose(fp);
00147         publicKey.publicKey = public_key;
00148         publicKey.publicKeyMode = RakNet::PKM_USE_KNOWN_PUBLIC_KEY;
00149 */
00150         //Do not connect when the interface is already connected
00151         if (m_rChatServerInterface && m_rChatServerInterface->NumberOfConnections() > 0) 
00152         {
00153             printf("Already connected!\n");
00154             return true;
00155         }
00156         //Start connecting
00157         m_rChatServerInterface = RakNet::RakPeerInterface::GetInstance();
00158         RakNet::SocketDescriptor serverSocket(SraNetwork::CLIENT_CHAT_PORT, 0);
00159         m_rChatServerInterface->Startup(1, &serverSocket, 1);
00160         //Convert wchar_t* -> char*
00161         char *saddr = new char[wcslen(serverAddress)+1];
00162         size_t res=0;
00163         wcstombs_s( &res, saddr, strlen(saddr), (const wchar_t*)serverAddress, strlen(saddr));
00164         //wcstombs(saddr, serverAddress, wcslen(serverAddress));
00165 
00166         printf("Connecting to chat server @ %s\n", saddr);
00167         RakNet::ConnectionAttemptResult result = 
00168             m_rChatServerInterface->Connect(saddr, SraNetwork::CHAT_CLIENT_PORT, 0, 0, &publicKey);
00169 
00170         // Only check if the connection attempt was succesfull, everything else will be handled by poll()
00171         if (result != RakNet::ConnectionAttemptResult::CONNECTION_ATTEMPT_STARTED)
00172         {
00173             return false;
00174         }
00175         return true;
00176     }
00177 
00182     __declspec(dllexport) bool SraReconnect()
00183     {
00184         return true;
00185     }
00186     
00190     __declspec(dllexport) void SraShutdown() 
00191     {
00192         if (m_rServerInterface) 
00193         {
00194             m_rServerInterface->CloseConnection( RakNet::UNASSIGNED_SYSTEM_ADDRESS, true, 0, HIGH_PRIORITY);
00195             m_rServerInterface->Shutdown(1000,0,HIGH_PRIORITY);
00196         }
00197     }
00198 
00199     __declspec(dllexport) void testServerForPackageOverflow()
00200     {
00201         if (!m_rServerInterface) {
00202             printf("Not connected !\n");
00203             return;
00204         }
00205         struct BigSraPacket {
00206         unsigned char opcode; //SraMessageIdentifiers
00207         int pID;
00208         wchar_t data[6000];
00209         };
00210 
00211         BigSraPacket bigpack;
00212         ZeroMemory(&bigpack, sizeof(bigpack));
00213         bigpack.pID = 12;
00214         bigpack.opcode = SraNetwork::ID_LOGIN_REQ;
00215         memset( bigpack.data, 1203, 6000);
00216         m_rServerInterface->Send( (char*)&bigpack, sizeof(bigpack), HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
00217     }
00218 
00224     __declspec(dllexport) bool SraLogin(const wchar_t* user, const wchar_t* pw)
00225     {
00226         if (!m_rServerInterface) {
00227             printf("Not connected !\n");
00228             return false;
00229         }
00230         LoginPacket packet;
00231         packet.opCode = SraNetwork::ID_LOGIN_REQ;
00232         packet.username = RakString(convertString(user).c_str());
00233         packet.password = RakString(convertString(pw).c_str());
00234 
00235         // Serialize packet
00236         RakNet::BitStream stream;
00237         packet.Serialize(&stream);
00238 
00239         // Send data
00240         uint32_t sentData = m_rServerInterface->Send( &stream,
00241             HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
00242         //printf("Done sending %d bytes\n", sentData);
00243         return true;
00244     }
00245 
00254     __declspec(dllexport) wchar_t* SraGetZone()
00255     {
00256         if (!m_rServerInterface || myPID == -1) 
00257         {
00258             printf("Not connected\n");
00259             return NULL;
00260         }
00261         return NULL;
00262         //SraNetwork::SraPacket packet;
00263         //ZeroMemory(&packet,sizeof(packet));
00264         //packet.opcode = SraNetwork::ID_CONNECT_TO_SRV;
00265         //packet.pID = myPID;
00267         //m_rServerInterface->Send( (char*)&packet, 
00268         //sizeof(packet), HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
00270         //bool done = false;
00271         //static wchar_t zoneAddress[SraNetwork::PACKAGE_DATA_SIZE];
00272         //RakNet::Packet* p;
00273         //while ( !done)
00274         //{
00275         //  p = m_rServerInterface->Receive();
00276         //  if (p) 
00277         //  {
00278         //      if (p->data[0] == SraNetwork::ID_CONNECT_TO_SRV) 
00279         //      {
00280         //          SraNetwork::SraPacket *sPack = (SraNetwork::SraPacket*)p->data;
00281         //          wcscpy_s( zoneAddress, sPack->data);
00282 
00283         //      } else 
00284         //      {
00285         //          printf("Invalid packet received\n");
00286         //      }
00287         //      done = true;
00288         //  }
00289         //  m_rServerInterface->DeallocatePacket(p);
00290         //}
00291         //return zoneAddress;
00292     }
00293 
00294     
00295     __declspec(dllexport) bool SraJoinChannel( int channelID )
00296     {
00297         if (!m_rServerInterface) {
00298             printf("Not connected !\n");
00299             return false;
00300         }
00301 
00302         JoinChannelPacket p;
00303         p.channelId = channelID;
00304 
00305         BitStream stream;
00306         p.Serialize(&stream);
00307 
00308         m_rServerInterface->Send( &stream, 
00309         HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
00310 
00311         return true;
00312     }
00313 
00314     __declspec(dllexport) bool SraLeaveChannel( int channelID )
00315     {
00316         if (!m_rServerInterface) {
00317             printf("Not connected !\n");
00318             return false;
00319         }
00320 
00321         LeaveChannelPacket p;
00322         p.channelId = channelID;
00323 
00324         BitStream stream;
00325         p.Serialize(&stream);
00326 
00327         m_rServerInterface->Send( &stream, 
00328         HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
00329 
00330         return true;
00331     }
00332 
00333     //Sends a message to the server
00334     __declspec(dllexport) bool SraSendMessage(const wchar_t* msg) 
00335     {
00336         if (!m_rChatServerInterface) {
00337             printf("Not connected !\n");
00338             return false;
00339         }
00340 
00341         SendMessageToChannelPacket p;
00342         p.channelId = 0;
00343         p.chatMessage =RakNet::RakString(convertString(msg).c_str());
00344         BitStream stream;
00345         p.Serialize(&stream);
00346         
00347         m_rChatServerInterface->Send( &stream, 
00348         HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
00349         
00350         return true;
00351     }
00352 
00353     
00354     __declspec(dllexport) bool SraCreateCharacter(int raceID, const wchar_t* name)
00355     {
00356         if (!m_rServerInterface) {
00357             printf("Not connected !\n");
00358             return false;
00359         }
00360 
00361         CreateCharacterPacket packet;
00362 
00363         packet.characterInfo.raceId = raceID;
00364         packet.characterInfo.charName = RakNet::RakString(convertString(name).c_str());
00365 
00366         RakNet::BitStream stream;
00367         packet.Serialize(&stream);
00368         m_rServerInterface->Send( &stream, 
00369             MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
00370 
00371         return true;
00372     }
00373 
00374     __declspec(dllexport) DEBUGServerReplyMessage Poll()
00375     {
00376         DEBUGServerReplyMessage result;
00377         memset(&result, 0, sizeof(DEBUGServerReplyMessage));
00378         result.resultCode = 0;
00379 
00380         // This methods should be called in every tick to process 
00381         // a message.
00382         if (!m_rServerInterface) {
00383             // Better not print a message in every tick :P
00384             //printf("Not connected!\n");
00385             result.resultCode = -1;
00386             result.message = L"Not connected to a server\n";
00387             return result;
00388         }
00389         RakNet::Packet *m_pPacket;
00390         m_pPacket = m_rServerInterface->Receive();
00391         if (m_pPacket) 
00392         {
00393             // First check the RakNet internals.
00394             if (m_pPacket->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) 
00395             {
00396                 result.message = L"Connected!\n";
00397                 result.resultCode = 1;
00398             } 
00399             //If the world server does not respond, RakNet will return a connection attempt failed packet
00400             else if (m_pPacket->data[0] == ID_CONNECTION_ATTEMPT_FAILED)
00401             {
00402                 result.message = L"Failed to connect!\n";
00403                 result.resultCode = -2;
00404             }
00405             else if (m_pPacket->data[0] == ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY)
00406             {
00407                 result.message = L"Remote systems requires public key!\n";
00408                 result.resultCode = -2;
00409             }
00410             else if (m_pPacket->data[0] == ID_OUR_SYSTEM_REQUIRES_SECURITY)
00411             {
00412                 result.message = L"Server does not support security!\n";
00413                 result.resultCode = -2;
00414             }
00415             else if (m_pPacket->data[0] == ID_PUBLIC_KEY_MISMATCH)
00416             {
00417                 result.message = L"Public key does not match server key!\n";
00418                 result.resultCode= -1;
00419             }
00420             else 
00421             {
00422                 // Now for our own packets. 
00423                 BitStream stream(m_pPacket->data, m_pPacket->length, false);
00424                 SraPacket sraPacket;
00425                 sraPacket.Deserialize(&stream);
00426 
00427                 switch (sraPacket.opCode)
00428                 {
00429                     case SraNetwork::ID_LOGIN_REP:
00430                         {
00431                             LoginReplyPacket login;
00432                             login.Deserialize(&stream);
00433                             // Switch between char and player Id
00434                             myPID = login.clientID;
00435                             result.message = L"Succesfully logged in!\n";
00436                             result.resultCode = 1;
00437                         }
00438                         break;
00439                     case SraNetwork::ID_SRA_REPLY:
00440                         {
00441                             ReplyPacket reply;
00442                             reply.Deserialize(&stream);
00443                             if (reply.replyCode == ReplyPacket::OK)
00444                             {
00445                                 switch (reply.messageOpCode)
00446                                 {
00447                                     case SraNetwork::ID_CREATE_CHAR:
00448                                     {
00449                                         result.message = L"Character successfully created\n";
00450                                         result.resultCode = 1;
00451                                     }
00452                                     case SraNetwork::ID_CHAT_CHANNEL_REGISTER:
00453                                     {
00454                                         result.message = convertString(reply.replyMessage.C_String());
00455                                         result.resultCode = 2;
00456                                     }
00457                                     break;
00458                                     default:
00459                                     break;
00460                                 }
00461                             }
00462                             else 
00463                             {
00464                                 switch (reply.messageOpCode)
00465                                 {
00466                                     case SraNetwork::ID_CREATE_CHAR:
00467                                     {
00468                                         result.message = convertString(reply.replyMessage.C_String());
00469                                         result.resultCode = -2;
00470                                     }
00471                                     break;
00472                                     case SraNetwork::ID_LOGIN_REP:
00473                                     {
00474                                         result.message = convertString(reply.replyMessage.C_String());
00475                                         result.resultCode = -2;
00476                                     }
00477                                     break;
00478                                 }
00479                             }
00480                         }
00481                         break;
00482                     default:
00483                         result.message = L"Invalid packet received\n";
00484                         result.resultCode = 1;
00485                         break;
00486                 }               
00487             }
00488             m_rServerInterface->DeallocatePacket(m_pPacket);
00489         }
00490         return result;
00491     }
00492 
00501     __declspec(dllexport) DEBUGServerReplyMessage PollChatMessages()
00502     {
00503         DEBUGServerReplyMessage result;
00504         memset(&result, 0, sizeof(DEBUGServerReplyMessage));
00505         result.resultCode = -100;
00506 
00507         if (!m_rChatServerInterface) {
00508             result.resultCode = -100;
00509             result.message = L"Not connected to a server\n";
00510             return result;
00511         }
00512 
00513         RakNet::Packet *m_pPacket;
00514         m_pPacket = m_rChatServerInterface->Receive();
00515 
00516         if (m_pPacket) 
00517         {
00518             // First check the RakNet internals.
00519             if (m_pPacket->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) 
00520             {
00521                 result.message = L"Connected to Chat server!\n";
00522                 result.resultCode = -1;
00523             } 
00524             //If the world server does not respond, RakNet will return a connection attempt failed packet
00525             else if (m_pPacket->data[0] == ID_CONNECTION_ATTEMPT_FAILED)
00526             {
00527                 result.message = L"Failed to connect to chat server!\n";
00528                 result.resultCode = -2;
00529             }
00530             else if (m_pPacket->data[0] == ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY)
00531             {
00532                 result.message = L"Remote systems requires public key!\n";
00533                 result.resultCode = -2;
00534             }
00535             else if (m_pPacket->data[0] == ID_OUR_SYSTEM_REQUIRES_SECURITY)
00536             {
00537                 result.message = L"Server does not support security!\n";
00538                 result.resultCode = -2;
00539             }
00540             else if (m_pPacket->data[0] == ID_PUBLIC_KEY_MISMATCH)
00541             {
00542                 result.message = L"Public key does not match server key!\n";
00543                 result.resultCode= -2;
00544             }
00545             else 
00546             {
00547                 // Now for our own packets. 
00548                 BitStream stream(m_pPacket->data, m_pPacket->length, false);
00549                 SraPacket sraPacket;
00550                 sraPacket.Deserialize(&stream);
00551 
00552                 switch (sraPacket.opCode)
00553                 {
00554                     case SraNetwork::ID_CHAT_CHANNEL_MESSAGE:
00555                         {
00556                             SendMessageToChannelPacket message;
00557                             message.Deserialize(&stream);
00558                             
00559                             result.message = convertString(message.chatMessage.C_String());
00560                             result.resultCode = message.channelId;
00561                         }
00562                         break;                  
00563                     default:
00564                         result.message = L"";
00565                         result.resultCode = -100;
00566                         break;
00567                 }               
00568             }
00569             m_rChatServerInterface->DeallocatePacket(m_pPacket);
00570         }
00571         return result;
00572     }
00573 }

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net