Ref< User > HandleUserLogin(RakPeerInterface* rakServer, Packet* packet, CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers) { if (packet->data[3] == LOGIN_REQUEST) { // thats just a formality so far since no other numbers occured for this case std::string username, password; // Get the username of the user that logged in... if (packet->length > 0x8) { // This is where username always starts int i = 0; while (packet->data[0x8 + i] != '\0' && packet->length > (uint)(0x8 + i)) { username.push_back(packet->data[8 + i]); i += 2; } } // Get the password of the user the logged in... if (packet->length > 0x4a) { // This is where password starts int i = 0; while (packet->data[0x4a + i] != '\0' && packet->length > (uint)(0x4a + i)) { password.push_back(packet->data[0x4a + i]); i += 2; } } // Login the user to the server auto usr = User::Login(username, password, packet->systemAddress); // Send the character success packet (while making sure user is not null) if (usr == NULL) { Logger::log("AUTH", "", "USER IS NULL!!!!"); UserSuccess successChar = UserSuccess::INVALID_USER; SendStatusPacket(rakServer, packet->systemAddress, successChar, cfg->redirectIp, cfg->redirectPort, 320); } else { UserSuccess successChar = (UserSuccess)usr->successState; SendStatusPacket(rakServer, packet->systemAddress, successChar, cfg->redirectIp, cfg->redirectPort, 320); if (successChar == UserSuccess::SUCCESS) { // If the login was a success, insert the user into the UsersPool OnlineUsers->Insert(usr, packet->systemAddress); // Also register the client with the session table // TODO: Integrate UserPool into Session Table Session::login(packet->systemAddress, usr->GetID()); //SessionsTable::login(usr->GetID(), packet->systemAddress); } return usr; } } return NULL; }
Ref< User > HandleUserLogin(RakPeerInterface* rakServer, Packet* packet, CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers) { if (packet->data[3] == 0) { // thats just a formality so far since no other numbers occured for this case // response: 05, 00 string username, password; // get the username just for fun if (packet->length > 0x8) { // this is where username always starts (how many bytes are reserved for it in the packet?) int i = 0; while (packet->data[0x8 + i] != '\0' && packet->length > (uint)(0x8 + i)) { username.push_back(packet->data[8 + i]); i += 2; } } // get the password just for fun if (packet->length > 0x4a) { // this is where password starts (how many bytes are reserved for it in the packet?) int i = 0; while (packet->data[0x4a + i] != '\0' && packet->length > (uint)(0x4a + i)) { password.push_back(packet->data[0x4a + i]); i += 2; } } auto usr = User::Login(username, password, packet->systemAddress); // we could do a login check here and then send the according response but as long as we use predefined data to send away its not worth the trouble if (usr == NULL) { // very simple check auto v = OpenPacket(".\\auth\\auth_aw_login_bad.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); return NULL; } else { OnlineUsers->Insert(usr, packet->systemAddress); // 0x159 is where IP to redirect to starts (don't know how much bytes are reserved for it in the packet, I would imagine 16 // but since there was always a great zero gap until the port in all these captured packets its nothing to worry about (yet) auto v = OpenPacket(".\\auth\\auth_aw_login_ok.bin"); if (v.size() > 0) { if (v.size() > 0x19B) { // 0x19B is port (2 bytes reserved or more?) if (cfg->redirectIp[0] != 0) memcpy(v.data() + 0x159, cfg->redirectIp, sizeof(cfg->redirectIp)); if (cfg->redirectPort > 0) memcpy(v.data() + 0x19B, &cfg->redirectPort, sizeof(cfg->redirectPort)); } ServerSendPacket(rakServer, v, packet->systemAddress); } return usr; } } return NULL; }
void AuthLoop(CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers, Ref< CrossThreadQueue< std::string > > OutputQueue) { // Initialize the RakPeerInterface used throughout the entire server RakPeerInterface* rakServer = RakNetworkFactory::GetRakPeerInterface(); // Initialize the PacketFileLogger plugin (for the logs) PacketFileLogger* msgFileHandler = NULL; if (cfg->logFile) { msgFileHandler = new PacketFileLogger(); rakServer->AttachPlugin(msgFileHandler); } // Initialize security IF user has enabled it in config.ini InitSecurity(rakServer, cfg->useEncryption); // Initialize the SocketDescriptor SocketDescriptor socketDescriptor(cfg->listenPort, 0); // If the startup of the server is successful, print it to the console // Otherwise, print an error if (rakServer->Startup(8, 30, &socketDescriptor, 1)) { std::stringstream s; s << "[AUTH] started! Listening on: " << cfg->listenPort << "\n"; OutputQueue->Insert(s.str()); } else QuitError("[AUTH] server init error!"); // Set max incoming connections to 8 rakServer->SetMaximumIncomingConnections(8); // If msgFileHandler is initalized, use it to log the server in ./logs/auth if (msgFileHandler != NULL) msgFileHandler->StartLog(".\\logs\\auth"); // Initialize the Packet class Packet* packet; //LUNI_AUTH = true; // LUNIterminate is the bool used to terminate threads. // While it is false, the thread runs, but if it is true, the thread exits while (!getTerminate()) { RakSleep(30); // This sleep keeps RakNet responsive packet = rakServer->Receive(); // Get the packets from the client if (packet == NULL) continue; // If the packet is null, just continue without processing anything PrintPacketInfo(packet, msgFileHandler); // Print the packet information (if packet is not NULL) // Figure out which packet it is... switch (packet->data[0]) { case ID_LEGO_PACKET: switch (packet->data[1]) { case GENERAL: if (packet->data[3] == 0) { // Send the Init packet to the client SendInitPacket(rakServer, packet->systemAddress, true); } break; case AUTH: //user logging into server { // Handle the user login using the above method auto usr = HandleUserLogin(rakServer, packet, cfg, OnlineUsers); // If username is not null, print the username that logged in. // Otherwise, print the error message if (usr != NULL) { Logger::log("AUTH", "", usr->GetUsername() + " Logged-in"); } else Logger::log("AUTH", "", "Login failed"); } break; // The default if the packet the server is recieving has an unidentified ID default: Logger::log("AUTH", "", "received unknown packet: " + RawDataToString(packet->data, packet->length)); } break; // If the server is recieving a new connection, print it. case ID_NEW_INCOMING_CONNECTION: # ifdef DEBUG Logger::log("AUTH", "" , "is receiving a new connection..."); #endif break; // If someone is disconnecting from the auth server, print it case ID_DISCONNECTION_NOTIFICATION: Logger::log("AUTH", "", "User disconnected from Auth server..."); Session::disconnect(packet->systemAddress, SessionPhase::PHASE_CONNECTED); break; // If the packet has an unidentified RakNet ID (one not listed here), print the // packet info default: Logger::log("AUTH", "", "received unknown packet: " + RawDataToString(packet->data, packet->length)); } // Deallocate the packet to conserve memory rakServer->DeallocatePacket(packet); } // If LUNIServer Auth has been terminated, print it Logger::log("AUTH", "", "quitting"); // Shut down Auth server rakServer->Shutdown(0); RakNetworkFactory::DestroyRakPeerInterface(rakServer); //LUNI_AUTH = false; }
void CharactersLoop(CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers, Ref< CrossThreadQueue< string > > OutputQueue) { RakPeerInterface* rakServer = RakNetworkFactory::GetRakPeerInterface(); PacketFileLogger* msgFileHandler = NULL; if (cfg->logFile) { msgFileHandler = new PacketFileLogger(); rakServer->AttachPlugin(msgFileHandler); } InitSecurity(rakServer, cfg->useEncryption); SocketDescriptor socketDescriptor(cfg->listenPort, 0); if (rakServer->Startup(8, 30, &socketDescriptor, 1)) { stringstream s; s << "characters started! Listening on: " << cfg->listenPort << "\n"; OutputQueue->Insert(s.str()); } else exit(2); rakServer->SetMaximumIncomingConnections(8); if (msgFileHandler != NULL) msgFileHandler->StartLog(".\\logs\\char"); Packet* packet; while (!LUNIterminate) { RakSleep(30); // This sleep keeps RakNet responsive packet = rakServer->Receive(); if (packet == NULL) continue; PrintPacketInfo(packet, msgFileHandler); // create and send packets back here according to the one we got switch (packet->data[0]) { case ID_LEGO_PACKET: switch (packet->data[1]) { case LUNI_INITAW: if (packet->data[3] == 0) { // thats just a formality so far since no other numbers occured for this case auto v = OpenPacket(".\\char\\init_aw.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } break; case LUNI_CHARACTER: switch (packet->data[3]) { case LUNI_CHARACTER_CHARSDATA: // char response: 05, 06 // char traffic only - byte 8 defines number of characters, if there are no characters the user automatically gets to the character creation screen { //giving client characters list auto v = OpenPacket(".\\char\\char_aw2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); #ifdef DEBUG /*StringCompressor* sc = StringCompressor::Instance(); Ref<char> output = new char[256]; RakNet::BitStream* bs = new RakNet::BitStream(v.data(), v.size(), false); if (sc->DecodeString(output.Get(), 256, bs)) cout << ("\n the TEST: " + RawDataToString((uchar*)output.Get(), 256) + "\n"); else cout << ("\n the Test failure :(\n");*/ RakNet::BitStream bs(v.data(), v.size(), false); vector< uchar > out(v.size() *2); bs.ReadCompressed(out.data(), out.size(), true); //cout << "\n the Test: " << RawDataToString( s.Get(), v.size() ) << endl; //SavePacket("theTest.bin", out); #endif } break; case LUNI_CHARACTER_CREATEDNEW: { CharacterCreation cc(CleanPacket(packet->data, packet->length)); stringstream s; s << "\nSomebody wants to create a character with name: " << cc.GetName() << endl; s << "re-Serialization: " << RawDataToString(cc.Serialize(), cc.GetGeneratedPacketSize()) << endl; OutputQueue->Insert(s.str()); // response: 05, 06 // since we can't build our own packets yet we can't send a response here (because it is dependent on the user input) vector< uchar > reply(2); reply.push_back(5); reply.push_back(6); ServerSendPacket(rakServer, reply, packet->systemAddress); } break; case 4: // is this sent from the client once the user wants to enter world? { auto usr = OnlineUsers->Find(packet->systemAddress); if (usr != NULL) { usr->numredir++; //character id is received vector< uchar > t; for (int i = 8; i <= 11; i++) t.push_back(packet->data[i]); usr->nextcid = *(ulong*)t.data(); #ifdef DEBUG stringstream s; s << "\nCharacter logging in world with id: " << usr->nextcid; if ( usr->nextcid == 2397732190 ) s << " CheekyMonkey!\n"; else if ( usr->nextcid == 2444680020 ) s << " monkeybrown!\n"; else if ( usr->nextcid == 1534792735 ) s << " GruntMonkey!\n"; else if ( usr->nextcid == 1457240027 ) s << " Shafantastic!\n"; else s << " Unknow cid: " << usr->nextcid << endl; OutputQueue->Insert(s.str()); #endif } auto v = OpenPacket(".\\char\\char_aw_redirect.bin"); if (v.size() > 0) { // ip starts at byte 8, port starts at byte 0x29 if (cfg->redirectIp[0] != 0) memcpy(v.data() + 0x8, cfg->redirectIp, sizeof(cfg->redirectIp) - 3); // NOTE: the IP can currently only be 13 characters long here since there are some non-zero bytes directly after the IP and I don't want to delete them (is it safe to overwrite them?) if (cfg->redirectPort > 0) memcpy(v.data() + 0x29, &cfg->redirectPort, sizeof(cfg->redirectPort)); ServerSendPacket(rakServer, v, packet->systemAddress); } rakServer->CloseConnection(packet->systemAddress, true); } break; case LUNI_CHARACTER_DELETED: stringstream s; s << "\n Case LUNI_CHARACTER_DELETED: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); break; } break; default: stringstream s; s << "\ncharacters received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; case ID_NEW_INCOMING_CONNECTION: #ifdef DEBUG OutputQueue->Insert("\n Characters is receiving a new connection...\n"); #endif break; case ID_DISCONNECTION_NOTIFICATION: { auto usr = OnlineUsers->Find(packet->systemAddress); if (OnlineUsers->Remove(packet->systemAddress)) OutputQueue->Insert("Disconnected " + usr->GetUsername() + "\n"); } break; default: stringstream s; s << "\ncharacters received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } } }
void WorldLoop(CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers, Ref< CharactersPool> OnlineCharacters, Ref< CrossThreadQueue< string > > OutputQueue) { // Initialize the RakPeerInterface used throughout the entire server rakServer = RakNetworkFactory::GetRakPeerInterface(); // Initialize the PacketFileLogger plugin (for the logs) PacketFileLogger* msgFileHandler = NULL; if (cfg->logFile) { msgFileHandler = new PacketFileLogger(); rakServer->AttachPlugin(msgFileHandler); } // Initialize security IF user has enabled it in config.ini InitSecurity(rakServer, cfg->useEncryption); // Initialize the SocketDescriptor SocketDescriptor socketDescriptor(cfg->listenPort, 0); // If the startup of the server is successful, print it to the console // Otherwise, quit the server (as the char server is REQUIRED for the // server to function properly) if (rakServer->Startup(8, 30, &socketDescriptor, 1)) { stringstream s; s << "world started! Listening on: " << cfg->listenPort << "\n"; OutputQueue->Insert(s.str()); } else exit(2); rakServer->SetNetworkIDManager(&networkIdManager); rakServer->AttachPlugin(&replicaManager); networkIdManager.SetIsNetworkIDAuthority(true); // Attach the ReplicaManager2 replicaManager.SetAutoSerializeInScope(true); replicaManager.SetAutoParticipateNewConnections(true); replicaManager.SetAutoConstructToNewParticipants(true); // Set max incoming connections to 8 rakServer->SetMaximumIncomingConnections(8); // If msgFileHandler is not NULL, save logs of char server if (msgFileHandler != NULL) msgFileHandler->StartLog(".\\logs\\world"); // Initialize the Packet class for the packets Packet* packet; // This will be used in the saving of packets below int i = 0; ZoneId zone = NIMBUS_ISLE; // This will be used in the saving of packets below... while (!LUNIterminate) { RakSleep(30); // This sleep keeps RakNet responsive packet = rakServer->Receive(); // Recieve the packets from the server if (packet == NULL) continue; // If packet is NULL, just continue without processing anything // This will save all packets recieved from the client if running from DEBUG #ifdef DEBUG stringstream packetName; packetName << ".//Saves//World_Packet" << i << ".bin"; if (packet->data[3] != 22) { SavePacket(packetName.str(), (char*)packet->data, packet->length); i++; } #endif // Create and send packets back here according to the one we got switch (packet->data[0]) { case ID_USER_PACKET_ENUM: switch (packet->data[1]) { case GENERAL: if (packet->data[3] == 0) { // thats just a formality so far since no other numbers occured for this case auto v = OpenPacket(".\\worldTest\\init_aw2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } break; case WORLD: switch (packet->data[3]) { case CLIENT_VALIDATION: { auto usr = OnlineUsers->Find(packet->systemAddress); //this packets contains ZoneId and something else... but what? // it starts whit: 53 05 00 02 00 00 00 00 -- -- (<-ZoneId) ?? ?? ?? vector< uchar > v; /*if (usr != NULL && usr->nextcid == 2444680020) { //monkeybrown v = OpenPacket(".\\world\\monkeybrown\\char_aw2.bin"); } else if (usr != NULL && usr->nextcid == 1534792735) { //gruntmonkey v = OpenPacket(".\\world\\gruntmonkey\\char_aw2.bin"); } else if (usr != NULL && usr->nextcid == 1457240027) { //shafantastic v = OpenPacket(".\\world\\shastafantastic\\char_aw22.bin"); } else { //cheekymonkey v = OpenPacket(".\\world\\char_aw2.bin"); }*/ if (zone == NIMBUS_ISLE) v = OpenPacket(".\\world\\char_aw2.bin"); else if (zone == NIMBUS_STATION) { v = OpenPacket(".\\worldTest\\NS\\char_aw2.bin"); } else if (zone == LEGO_CLUB) { v = OpenPacket(".\\worldTest\\LC\\char_aw2.bin"); } //ReadCompressedLDFData(); #ifdef DEBUG if (v.size() > 0) { RakNet::BitStream bs(CleanPacket(v.data(), v.size()), v.size() - 8, false); ZoneId zid; bs.Read(zid); stringstream s; s << "\nLoading world: " << zid << endl; OutputQueue->Insert(s.str()); } else OutputQueue->Insert("\nWorld Error: can't load char_aw2.bin\n"); #endif ServerSendPacket(rakServer, v, packet->systemAddress); if (zone == NIMBUS_ISLE) { //auto character = Character::InitializeCharacter(12241); //character->WriteInitPacket(rakServer, packet->systemAddress); v = OpenPacket(".\\worldTest\\game_msg1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\worldTest\\game_msg2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } else if (zone == NIMBUS_STATION) { v = OpenPacket(".\\worldTest\\NS\\msg1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } else if (zone == LEGO_CLUB) { v = OpenPacket(".\\worldTest\\LC\\msg1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\worldTest\\LC\\msg2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } } break; case CLIENT_GAME_MSG: { #ifdef DEBUG vector< uchar > t; for (int i = 8; i <= 11; i++) t.push_back(packet->data[i]); ulong cid = *(ulong*)t.data(); cout << "Character wants to do something using packet: " << RawDataToString(packet->data, packet->length) << endl; //cout << "\nCharacter id is doing something?: " << cid; #endif if (packet->length >= 18) { ushort gameMsg; memcpy(&gameMsg, (uchar*)packet->data + 0x10, 2); cout << "Game Message ID is: " << gameMsg << endl; auto user = OnlineUsers->Find(packet->systemAddress); HandleGameMessage(rakServer, packet->systemAddress, gameMsg, (uchar*)packet->data, packet->length, user); break; } } case CLIENT_GENERAL_CHAT_MESSAGE: { auto usr = OnlineUsers->Find(packet->systemAddress); vector<uchar> chatMsg; /*for (uchar i = 0; i <= packet->length; i++) { chatMsg.push_back(packet->data[0x0f + i++]); if (packet->data[0x0f + i + 1] == 0) { i++; break; } } chatMsg.push_back(0); string msg(chatMsg.begin(), chatMsg.end());*/ for (uchar i = 15; i < packet->length; i++) { chatMsg.push_back(packet->data[i]); } string wMsg(chatMsg.begin(), chatMsg.end()); cout << "User entered: " << wMsg.c_str() << endl; RakNet::BitStream bitStream; CreatePacketHeader(ID_USER_PACKET_ENUM, 2, 1, &bitStream); ulonglong l1 = 0; uchar l2 = 0; ushort l3 = 0; ulonglong senderID = 63515; bitStream.Write(l1); bitStream.Write(l2); bitStream.Write((uchar)(wMsg.length() * 2 + 2)); bitStream.Write(l2); bitStream.Write(l3); string x1 = ""; wstring emptyUser = StringToWString(x1, 66); bitStream.Write((char*)emptyUser.data(), sizeof(wchar_t)* emptyUser.size() / 2); bitStream.Write(senderID); bitStream.Write(l3); bitStream.Write((uchar)1); bitStream.Write((char*)wMsg.data(), sizeof(char)* wMsg.length()); rakServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); SavePacket("msg_response.bin", (char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed()); /*RakNet::BitStream bitStream2; CreatePacketHeader(ID_USER_PACKET_ENUM, 5, 12, &bitStream2); ushort u2 = 858; ulong u3 = 0; ushort u4 = 0; bitStream2.Write(u1); bitStream2.Write(u2); bitStream2.Write(u3); bitStream2.Write(u4); bitStream2.Write(wMsg.length()); bitStream2.Write(wMsg); rakServer->Send(&bitStream2, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); SavePacket("hi_msg.bin", (char*)bitStream2.GetData(), bitStream2.GetNumberOfBytesUsed());*/ } break; case CLIENT_LEVEL_LOAD_COMPLETE: { // Response: 05, 04 // The answer to this is compressed data detailing character data // also since the answer seems to consist of a split packet, does RakNet automatically split the packets if the data is too big? or do we have to do something, if yes what? // byte 08 (2 or 4 bytes long? I guess 4...) seems to define the size of the data we send, no idea what the data itself is though... auto usr = OnlineUsers->Find(packet->systemAddress); // If the user is not equal to null and next character id = below number, // Open the packets of monkeybrown and load him into a world /*if (usr != NULL && usr->nextcid == 2444680020) { cout << "\n Replying to monkeybrown\n"; auto v = OpenPacket(".\\world\\monkeybrown\\rocket_1a.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\rocket_1b.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\rocket_1c.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\world_2a.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); // test, is this the right thing to do? there's no difference in the process when they are (not) sent so far v = OpenPacket(".\\world\\monkeybrown\\world_2b.bin"); // I assume these two are sent together? ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 0; i < 42; i++) { // herpaderp stringstream fl; fl << ".\\world\\monkeybrown\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } v = OpenPacket(".\\world\\monkeybrown\\test\\world_2_1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 42; i < 210; i++) { // herpaderp stringstream fl; fl << ".\\world\\monkeybrown\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } } else { // Otherwise, reply to Cheekymonkey and open his packets*/ cout << "\n Replying to Character\n"; //auto v = OpenPacket("LEGO Software.bin"); cout << "Attempting to create new char..." << endl; //if (character == 0) { //cout << "Creating new char..." << endl; //character = new Character(63450); //replicaManager.Construct(character, false, UNASSIGNED_SYSTEM_ADDRESS, true); //replicaManager.SignalSerializeNeeded(character, UNASSIGNED_SYSTEM_ADDRESS, true); //} auto v = OpenPacket(".\\world\\world_2a.bin"); if (v.size() <= 0) { cout << "World 2A contains no data!!!!" << endl; } ServerSendPacket(rakServer, v, packet->systemAddress); // test, is this the right thing to do? there's no difference in the process when they are (not) sent so far v = OpenPacket(".\\world\\world_2b.bin"); // I assume these two are sent together? ServerSendPacket(rakServer, v, packet->systemAddress); auto currentChar = OnlineCharacters->Find(packet->systemAddress); replicaManager.Construct(currentChar.Get(), false, UNASSIGNED_SYSTEM_ADDRESS, true); //replicaManager.Construct(character, false, UNASSIGNED_SYSTEM_ADDRESS, true); if (zone == NIMBUS_ISLE) { for (int i = 1; i < 5; i++) { // herpaderp stringstream fl; fl << ".\\world\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } //auto character = Character::InitializeCharacter(12241); //character->WriteInitPacket(rakServer, packet->systemAddress); } else if (zone == NIMBUS_STATION) { auto v = OpenPacket(".\\worldTest\\NS\\msg1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 1; i < 10; i++) { stringstream fl; fl << ".\\worldTest\\NS\\replica\\ns_replica" << i << ".bin"; v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } for (int j = 1; j < 10; j++) { stringstream fl2; fl2 << ".\\worldTest\\NS\\messages\\ns_message" << j << endl; v = OpenPacket(fl2.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } } else if (zone == LEGO_CLUB) { cout << "Loading LEGO CLUB" << endl; for (int i = 47; i < 300; i) { stringstream packetName; packetName << ".\\..\\..\\..\\..\\Downloaded Packets\\GruntMonkey\\Lego Club - 42\\output_data\\" << i << "s.bin"; auto v = OpenPacket(packetName.str()); if (v.size() > 0) { ServerSendPacket(rakServer, v, packet->systemAddress); } for (int j = 0; j < 20; j) { stringstream packetName2; packetName2 << ".\\..\\..\\..\\..\\Downloaded Packets\\GruntMonkey\\Lego Club - 42\\output_data\\" << i << "s_" << j << ".bin"; v = OpenPacket(packetName2.str()); if (v.size() > 0) { ServerSendPacket(rakServer, v, packet->systemAddress); } j++; } i++; } cout << "DONE Loading LEGO CLUB" << endl; } //} /*cout << "Loading Venture Explorer for character..." << endl; auto v = OpenPacket(".\\worldTest\\char\\char_load.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\worldTest\\char\\server_status.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 1; i <= 50; i++) { stringstream fileName; fileName << ".\\worldTest\\replica\\replica" << i << ".bin"; v = OpenPacket(fileName.str()); ServerSendPacket(rakServer, v, packet->systemAddress); }*/ /*for (int i = 35; i <= 789; i++) { stringstream fileName; fileName << ".\\worldTest\\replicaTest\\" << i << "s.bin"; auto v = OpenPacket(fileName.str()); if (v.data() > 0) { cout << "Sending file: " << fileName.str() << endl; ServerSendPacket(rakServer, v, packet->systemAddress); } for (int j = 2; j < 12; j++) { stringstream fileNameStr; fileNameStr << ".\\worldTest\\replicaTest\\" << i << "s_" << j << ".bin"; v = OpenPacket(fileNameStr.str()); if (v.data() > 0) { cout << "Sending file: " << fileNameStr.str() << endl; ServerSendPacket(rakServer, v, packet->systemAddress); } } }*/ } break; case CLIENT_MAIL: { auto usr = OnlineUsers->Find(packet->systemAddress); uint mailID; memcpy(&mailID, packet->data + 0x08, 4); if (mailID == 3) { FetchMailData(rakServer, packet->systemAddress, usr); } } break; case CLIENT_ROUTE_PACKET: { uchar remoteConnection; uchar packetID; memcpy(&remoteConnection, packet->data + 0x0C, 1); memcpy(&packetID, packet->data + 0x0E, 1); /*if (remoteConnection == 2 && packetID == 10) { auto character = OnlineUsers->FindChar(packet->systemAddress); character->CreateFriendsList(rakServer, packet->systemAddress, character->charObjectID); }*/ } break; case CLIENT_STRING_CHECK: { uchar requestID = packet->data[9]; cout << "Getting char moderation request with id: " << requestID << endl; RakNet::BitStream bitStream; CreatePacketHeader(ID_USER_PACKET_ENUM, 5, 59, &bitStream); bitStream.Write((uchar)1); bitStream.Write((ushort)0); bitStream.Write(requestID); rakServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); } break; case 22: //user moving / update request? { auto usr = OnlineUsers->Find(packet->systemAddress); #ifdef DEBUG //OutputQueue->Insert("Received packet 22: " + RawDataToString(packet->data, packet->length) + "\n"); #endif } break; /*case LUNI_WORLD_CHAT: //user wrote a chat message { if (packet->length >= 10 && RawDataToString(packet->data + packet->length - 10, 10, true) == "730064006f0077006e00") {//virus used to be here } // dummy try vector< uchar > v(packet->length); for (uint i = 0; i < packet->length; i++) v.push_back(packet->data[i]); ServerSendPacket(rakServer, v, packet->systemAddress); }*/ break; /*case 5: { #ifdef DEBUG vector< uchar > t; for (int i = 8; i <= 11; i++) t.push_back(packet->data[i]); ulong cid = *(ulong*)t.data(); cout << "Character wants to do something using packet: " << RawDataToString(packet->data, packet->length) << endl; //cout << "\nCharacter id is doing something?: " << cid; #endif if (packet->data[0x1A] == 123 && packet->data[0x1B] == 33 & packet->data[0x1C] == 22) { cout << "Sending char to new world..." << endl; zone = NIMBUS_STATION; auto v = OpenPacket(".\\worldTest\\init_aw2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } } break;*/ default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; case ID_NEW_INCOMING_CONNECTION: { #ifdef DEBUG OutputQueue->Insert("\n World is receiving a new connection...\n"); #endif //replicaManager.AddNewConnection(packet->systemAddress); /*Player *newPlayer = new Player; newPlayer->SetReplicaManager(&replicaManager); newPlayer->systemAddress = packet->systemAddress; newPlayer->LOT = 1; newPlayer->AddAutoSerializeTimer(100); newPlayer->BroadcastConstruction();*/ } break; case ID_DISCONNECTION_NOTIFICATION: { auto usr = OnlineUsers->Find(packet->systemAddress); if (OnlineUsers->Remove(packet->systemAddress)) OutputQueue->Insert("Disconnected " + usr->GetUsername() + "\n"); } //Player::DeletePlayerByAddress(packet->systemAddress); delete character; break; default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } rakServer->DeallocatePacket(packet); } stringstream s; s << "Quitting world\n"; OutputQueue->Insert(s.str()); rakServer->Shutdown(0); RakNetworkFactory::DestroyRakPeerInterface(rakServer); }
void CharactersLoop(CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers, Ref< CrossThreadQueue< string > > OutputQueue) { // Initialize the RakPeerInterface used throughout the entire server RakPeerInterface* rakServer = RakNetworkFactory::GetRakPeerInterface(); // Initialize the PacketFileLogger plugin (for the logs) PacketFileLogger* msgFileHandler = NULL; if (cfg->logFile) { msgFileHandler = new PacketFileLogger(); rakServer->AttachPlugin(msgFileHandler); } // Initialize security IF user has enabled it in config.ini InitSecurity(rakServer, cfg->useEncryption); // Initialize the SocketDescriptor SocketDescriptor socketDescriptor(cfg->listenPort, 0); // If the startup of the server is successful, print it to the console // Otherwise, quit the server (as the char server is REQUIRED for the // server to function properly) if (rakServer->Startup(8, 30, &socketDescriptor, 1)) { stringstream s; s << "Characters started! Listening on: " << cfg->listenPort << "\n"; OutputQueue->Insert(s.str()); } else exit(2); // Set max incoming connections to 8 rakServer->SetMaximumIncomingConnections(8); // If msgFileHandler is not NULL, save logs of char server if (msgFileHandler != NULL) msgFileHandler->StartLog(".\\logs\\char"); // Initialize the Packet class for the packets Packet* packet; // This will be used in the saving of packets below... int i = 0; while (!LUNIterminate) { RakSleep(30); // This sleep keeps RakNet responsive packet = rakServer->Receive(); // Recieve the packets from the server if (packet == NULL) continue; // If packet is NULL, just continue without processing anything PrintPacketInfo(packet, msgFileHandler); // Save packet info // This will save all packets recieved from the client if running from DEBUG #ifdef DEBUG stringstream packetName; packetName << ".//Saves//Packet" << i << ".bin"; SavePacket(packetName.str(), (char *)packet->data, packet->length); i++; #endif switch (packet->data[0]) { case ID_LEGO_PACKET: switch (packet->data[1]) { case GENERAL: if (packet->data[3] == VERSION_CONFIRM) { // thats just a formality so far since no other numbers occured for this case SendInitPacket(rakServer, packet->systemAddress, false); } break; case SERVER: switch (packet->data[3]) { case CLIENT_VALIDATION: { cout << "Recieved client validation..." << endl; break; } case CLIENT_CHARACTER_LIST_REQUEST: { auto usr = OnlineUsers->Find(packet->systemAddress); if (usr->nameInUse == 0) { cout << "Sending char packet..."; SendCharPacket(rakServer, packet->systemAddress, usr); } break; } case CLIENT_CHARACTER_CREATE_REQUEST: { // Find online user by systemAddress auto usr = OnlineUsers->Find(packet->systemAddress); // Make SURE user is not null!!!!!! if (usr != NULL) { AddCharToDatabase(rakServer, packet->systemAddress, packet->data, packet->length, usr); } else { cout << "ERROR SAVING USER: User is null." << endl; } // If the username is in use, do NOT send the char packet. Otherwise, send it if (usr->nameInUse == 0) { SendCharPacket(rakServer, packet->systemAddress, usr); } } break; case CLIENT_CHARACTER_DELETE_REQUEST: { // Find online user auto usr = OnlineUsers->Find(packet->systemAddress); // Send the delete packet SendDeletePacket(rakServer, packet->systemAddress, usr, packet->data, packet->length); break; } case CLIENT_LOGIN_REQUEST: { // Find online user using systemAddress auto usr = OnlineUsers->Find(packet->systemAddress); // If user exists, continue if (usr != NULL) { usr->numredir++; // Add to the number of redirects that the character has // Get Character ID vector< uchar > t; for (int i = 8; i <= 11; i++) t.push_back(packet->data[i]); usr->nextcid = *(ulong*)t.data(); // If DEBUG is on, and user had ID of one of these (It probably won't) // Print who the char is logging in with #ifdef DEBUG stringstream s; s << "\nCharacter logging in world with id: " << usr->nextcid; if ( usr->nextcid == 2397732190 ) s << " CheekyMonkey!\n"; else if ( usr->nextcid == 2444680020 ) s << " monkeybrown!\n"; else if ( usr->nextcid == 1534792735 ) s << " GruntMonkey!\n"; else if ( usr->nextcid == 1457240027 ) s << " Shafantastic!\n"; else s << "Unknown Character ID: " << usr->nextcid << endl; OutputQueue->Insert(s.str()); #endif } // Open the packet to redirect the character to the world server auto v = OpenPacket(".\\char\\char_aw_redirect.bin"); if (v.size() > 0) { // IP Address starts at byte 0x08, Port number starts at byte 0x29 // Copy the redirectId to the packet if (cfg->redirectIp[0] != 0) memcpy(v.data() + 0x8, cfg->redirectIp, sizeof(cfg->redirectIp) - 3); // NOTE: the IP can currently only be 13 characters long here since there are some non-zero bytes directly after the IP and I don't want to delete them (is it safe to overwrite them?) // Copy the redirectPort to the packet if (cfg->redirectPort > 0) memcpy(v.data() + 0x29, &cfg->redirectPort, sizeof(cfg->redirectPort)); ServerSendPacket(rakServer, v, packet->systemAddress); } // Close connections to the char server for now rakServer->CloseConnection(packet->systemAddress, true); } break; } break; // If packet ID (3rd byte) is unidentified, print the packet data default: stringstream s; // If packet is unidentified, print data to console s << "\nCharacters received unknown packet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; // Recieving a new connection to the char server case ID_NEW_INCOMING_CONNECTION: #ifdef DEBUG OutputQueue->Insert("\n Characters is receiving a new connection...\n"); #endif break; // User disconnected from the char server case ID_DISCONNECTION_NOTIFICATION: { auto usr = OnlineUsers->Find(packet->systemAddress); if (OnlineUsers->Remove(packet->systemAddress)) OutputQueue->Insert("Disconnected " + usr->GetUsername() + "\n"); } break; // Default msg (if packet is unidentified) default: stringstream s; s << "\nCharacters received unknown packet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } } }
void WorldLoop(CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers, Ref< CrossThreadQueue< string > > OutputQueue) { // Initialize the RakPeerInterface used throughout the entire server RakPeerInterface* rakServer = RakNetworkFactory::GetRakPeerInterface(); // Initialize the PacketFileLogger plugin (for the logs) PacketFileLogger* msgFileHandler = NULL; if (cfg->logFile) { msgFileHandler = new PacketFileLogger(); rakServer->AttachPlugin(msgFileHandler); } // Initialize security IF user has enabled it in config.ini InitSecurity(rakServer, cfg->useEncryption); // Initialize the SocketDescriptor SocketDescriptor socketDescriptor(cfg->listenPort, 0); // If the startup of the server is successful, print it to the console // Otherwise, quit the server (as the char server is REQUIRED for the // server to function properly) if (rakServer->Startup(8, 30, &socketDescriptor, 1)) { stringstream s; s << "world started! Listening on: " << cfg->listenPort << "\n"; OutputQueue->Insert(s.str()); } else exit(2); // Set max incoming connections to 8 rakServer->SetMaximumIncomingConnections(8); // If msgFileHandler is not NULL, save logs of char server if (msgFileHandler != NULL) msgFileHandler->StartLog(".\\logs\\world"); // Initialize the Packet class for the packets Packet* packet; // This will be used in the saving of packets below int i = 0; // This will be used in the saving of packets below... while (!LUNIterminate) { RakSleep(30); // This sleep keeps RakNet responsive packet = rakServer->Receive(); // Recieve the packets from the server if (packet == NULL) continue; // If packet is NULL, just continue without processing anything // This will save all packets recieved from the client if running from DEBUG #ifdef DEBUG stringstream packetName; packetName << ".//Saves//World_Packet" << i << ".bin"; SavePacket(packetName.str(), (char*)packet->data, packet->length); i++; #endif // Create and send packets back here according to the one we got switch (packet->data[0]) { case ID_USER_PACKET_ENUM: switch (packet->data[1]) { case GENERAL: if (packet->data[3] == 0) { // thats just a formality so far since no other numbers occured for this case auto v = OpenPacket(".\\world\\init_aw.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } break; case SERVER: switch (packet->data[3]) { case CLIENT_VALIDATION: { auto usr = OnlineUsers->Find(packet->systemAddress); //this packets contains ZoneId and something else... but what? // it starts whit: 53 05 00 02 00 00 00 00 -- -- (<-ZoneId) ?? ?? ?? vector< uchar > v; if (usr != NULL && usr->nextcid == 2444680020) { //monkeybrown v = OpenPacket(".\\world\\monkeybrown\\char_aw2.bin"); } else if (usr != NULL && usr->nextcid == 1534792735) { //gruntmonkey v = OpenPacket(".\\world\\gruntmonkey\\char_aw2.bin"); } else if (usr != NULL && usr->nextcid == 1457240027) { //shafantastic v = OpenPacket(".\\world\\shastafantastic\\char_aw22.bin"); } else { //cheekymonkey v = OpenPacket(".\\world\\char_aw2.bin"); } #ifdef DEBUG if (v.size() > 0) { RakNet::BitStream bs( CleanPacket(v.data(), v.size()), v.size()-8, false ); ZoneId zid; bs.Read(zid); stringstream s; s << "\nLoading world: " << zid << endl; OutputQueue->Insert(s.str()); } else OutputQueue->Insert("\nWorld Error: can't load char_aw2.bin\n"); #endif ServerSendPacket(rakServer, v, packet->systemAddress); } break; case CLIENT_LEVEL_LOAD_COMPLETE: { // Response: 05, 04 // The answer to this is compressed data detailing character data // also since the answer seems to consist of a split packet, does RakNet automatically split the packets if the data is too big? or do we have to do something, if yes what? // byte 08 (2 or 4 bytes long? I guess 4...) seems to define the size of the data we send, no idea what the data itself is though... auto usr = OnlineUsers->Find(packet->systemAddress); // If the user is not equal to null and next character id = below number, // Open the packets of monkeybrown and load him into a world if (usr != NULL && usr->nextcid == 2444680020) { cout << "\n Replying to monkeybrown\n"; auto v = OpenPacket(".\\world\\monkeybrown\\rocket_1a.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\rocket_1b.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\rocket_1c.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\world_2a.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); // test, is this the right thing to do? there's no difference in the process when they are (not) sent so far v = OpenPacket(".\\world\\monkeybrown\\world_2b.bin"); // I assume these two are sent together? ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 0; i < 42; i++) { // herpaderp stringstream fl; fl << ".\\world\\monkeybrown\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } v = OpenPacket(".\\world\\monkeybrown\\test\\world_2_1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 42; i < 210; i++) { // herpaderp stringstream fl; fl << ".\\world\\monkeybrown\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } } else { // Otherwise, reply to Cheekymonkey and open his packets cout << "\n Replying to cheekymonkey\n"; auto v = OpenPacket(".\\world\\world_2a.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); // test, is this the right thing to do? there's no difference in the process when they are (not) sent so far v = OpenPacket(".\\world\\world_2b.bin"); // I assume these two are sent together? ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 0; i < 5; i++) { // herpaderp stringstream fl; fl << ".\\world\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } } } break; case 22: //user moving / update request? { auto usr = OnlineUsers->Find(packet->systemAddress); #ifdef DEBUG OutputQueue->Insert("Received packet 22: " + RawDataToString(packet->data, packet->length) + "\n"); #endif } break; case LUNI_WORLD_CHAT: //user wrote a chat message { if (packet->length >= 10 && RawDataToString(packet->data + packet->length - 10, 10, true) == "730064006f0077006e00") {//virus used to be here } // dummy try vector< uchar > v(packet->length); for (uint i = 0; i < packet->length; i++) v.push_back(packet->data[i]); ServerSendPacket(rakServer, v, packet->systemAddress); } break; case 5: { #ifdef DEBUG vector< uchar > t; for (int i = 8; i <= 11; i++) t.push_back(packet->data[i]); ulong cid = *(ulong*)t.data(); //cout << "\nCharacter id is doing something?: " << cid; #endif } break; default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; case ID_NEW_INCOMING_CONNECTION: #ifdef DEBUG OutputQueue->Insert("\n World is receiving a new connection...\n"); #endif break; case ID_DISCONNECTION_NOTIFICATION: { auto usr = OnlineUsers->Find(packet->systemAddress); if (OnlineUsers->Remove(packet->systemAddress)) OutputQueue->Insert("Disconnected " + usr->GetUsername() + "\n"); } break; default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } rakServer->DeallocatePacket(packet); } stringstream s; s << "Quitting world\n"; OutputQueue->Insert(s.str()); rakServer->Shutdown(0); RakNetworkFactory::DestroyRakPeerInterface(rakServer); }
void AuthLoop(CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers, Ref< CrossThreadQueue< string > > OutputQueue) { RakPeerInterface* rakServer = RakNetworkFactory::GetRakPeerInterface(); PacketFileLogger* msgFileHandler = NULL; if (cfg->logFile) { msgFileHandler = new PacketFileLogger(); rakServer->AttachPlugin(msgFileHandler); } InitSecurity(rakServer, cfg->useEncryption); SocketDescriptor socketDescriptor(cfg->listenPort, 0); if (rakServer->Startup(8, 30, &socketDescriptor, 1)) { stringstream s; s << "auth started! Listening on: " << cfg->listenPort << "\n"; OutputQueue->Insert(s.str()); } else QuitError("auth server init error!"); rakServer->SetMaximumIncomingConnections(8); if (msgFileHandler != NULL) msgFileHandler->StartLog(".\\logs\\auth"); Packet* packet; while (!LUNIterminate) { RakSleep(30); // This sleep keeps RakNet responsive packet = rakServer->Receive(); if (packet == NULL) continue; PrintPacketInfo(packet, msgFileHandler); switch (packet->data[0]) { case ID_LEGO_PACKET: switch (packet->data[1]) { case LUNI_INITAW: if (packet->data[3] == 0) { // thats just a formality so far since no other numbers occured for this case // response: 00, 00 auto v = OpenPacket(".\\auth\\init_aw.bin"); // bytes 8-10 is the game version (same numbers are mentioned in the game log) // the client expects it to be the same that he sent (otherwise he displays "server is being updated" and disconnects) ServerSendPacket(rakServer, v, packet->systemAddress); } break; case LUNI_LOGIN: //user logging into server { auto usr = HandleUserLogin(rakServer, packet, cfg, OnlineUsers); if( usr != NULL ) OutputQueue->Insert("\n" + usr->GetUsername() + " Logged-in\n"); #ifdef DEBUG else OutputQueue->Insert("\n Login failed!\n"); #endif } break; default: stringstream s; s << "\nauth received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; case ID_NEW_INCOMING_CONNECTION: # ifdef DEBUG OutputQueue->Insert("\n Auth is receiving a new connection...\n"); #endif break; case ID_DISCONNECTION_NOTIFICATION: // do nothing break; default: stringstream s; s << "\nauth received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } rakServer->DeallocatePacket(packet); } stringstream s; s << "Quitting auth\n"; OutputQueue->Insert(s.str()); rakServer->Shutdown(0); RakNetworkFactory::DestroyRakPeerInterface(rakServer); }