void cb_login(AuthServer_Private& client) { Auth_LoginInfo msg; msg.m_client = &client; uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); msg.m_clientChallenge = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); msg.m_acctName = DS::CryptRecvString(client.m_sock, client.m_crypt); DS::CryptRecvBuffer(client.m_sock, client.m_crypt, msg.m_passHash.m_data, sizeof(DS::ShaHash)); msg.m_token = DS::CryptRecvString(client.m_sock, client.m_crypt); msg.m_os = DS::CryptRecvString(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_AuthClientLogin, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); if (reply.m_messageType != DS::e_NetSuccess) { static uint32_t zerokey[4] = { 0, 0, 0, 0 }; START_REPLY(e_AuthToCli_AcctLoginReply); client.m_buffer.write<uint32_t>(transId); client.m_buffer.write<uint32_t>(reply.m_messageType); client.m_buffer.writeBytes(client.m_acctUuid.m_bytes, sizeof(client.m_acctUuid.m_bytes)); client.m_buffer.write<uint32_t>(0); client.m_buffer.write<uint32_t>(0); client.m_buffer.writeBytes(zerokey, sizeof(zerokey)); SEND_REPLY(); return; } for (auto player_iter = msg.m_players.begin(); player_iter != msg.m_players.end(); ++player_iter) { START_REPLY(e_AuthToCli_AcctPlayerInfo); client.m_buffer.write<uint32_t>(transId); client.m_buffer.write<uint32_t>(player_iter->m_playerId); client.m_buffer.writePString<uint16_t>(player_iter->m_playerName, DS::e_StringUTF16); client.m_buffer.writePString<uint16_t>(player_iter->m_avatarModel, DS::e_StringUTF16); client.m_buffer.write<uint32_t>(player_iter->m_explorer); SEND_REPLY(); } /* The final reply */ START_REPLY(e_AuthToCli_AcctLoginReply); client.m_buffer.write<uint32_t>(transId); client.m_buffer.write<uint32_t>(DS::e_NetSuccess); client.m_buffer.writeBytes(client.m_acctUuid.m_bytes, sizeof(client.m_acctUuid.m_bytes)); client.m_buffer.write<uint32_t>(client.m_acctFlags); client.m_buffer.write<uint32_t>(msg.m_billingType); client.m_buffer.writeBytes(DS::Settings::DroidKey(), 4 * sizeof(uint32_t)); SEND_REPLY(); }
void cb_playerCreate(AuthServer_Private& client) { START_REPLY(e_AuthToCli_PlayerCreateReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_PlayerCreate msg; msg.m_client = &client; msg.m_player.m_playerName = DS::CryptRecvString(client.m_sock, client.m_crypt); msg.m_player.m_avatarModel = DS::CryptRecvString(client.m_sock, client.m_crypt); DS::CryptRecvString(client.m_sock, client.m_crypt); // Friend invite s_authChannel.putMessage(e_AuthCreatePlayer, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(0); // Player ID client.m_buffer.write<uint32_t>(0); // Explorer client.m_buffer.write<uint16_t>(0); // Player Name client.m_buffer.write<uint16_t>(0); // Avatar Model } else { client.m_buffer.write<uint32_t>(msg.m_player.m_playerId); client.m_buffer.write<uint32_t>(1); // Explorer client.m_buffer.writePString<uint16_t>(msg.m_player.m_playerName, DS::e_StringUTF16); client.m_buffer.writePString<uint16_t>(msg.m_player.m_avatarModel, DS::e_StringUTF16); } SEND_REPLY(); }
void cb_ageCreate(AuthServer_Private& client) { START_REPLY(e_AuthToCli_VaultInitAgeReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_AgeCreate msg; msg.m_client = &client; DS::CryptRecvBuffer(client.m_sock, client.m_crypt, msg.m_age.m_ageId.m_bytes, sizeof(msg.m_age.m_ageId.m_bytes)); DS::CryptRecvBuffer(client.m_sock, client.m_crypt, msg.m_age.m_parentId.m_bytes, sizeof(msg.m_age.m_parentId.m_bytes)); msg.m_age.m_filename = DS::CryptRecvString(client.m_sock, client.m_crypt); msg.m_age.m_instName = DS::CryptRecvString(client.m_sock, client.m_crypt); msg.m_age.m_userName = DS::CryptRecvString(client.m_sock, client.m_crypt); msg.m_age.m_description = DS::CryptRecvString(client.m_sock, client.m_crypt); msg.m_age.m_seqNumber = DS::CryptRecvValue<int32_t>(client.m_sock, client.m_crypt); msg.m_age.m_language = DS::CryptRecvValue<int32_t>(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_VaultInitAge, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(0); // Age Node Idx client.m_buffer.write<uint32_t>(0); // Age Info Node Idx } else { client.m_buffer.write<uint32_t>(msg.m_ageIdx); client.m_buffer.write<uint32_t>(msg.m_infoIdx); } SEND_REPLY(); }
void cb_nodeUpdate(AuthServer_Private& client) { START_REPLY(e_AuthToCli_VaultSaveNodeReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_NodeInfo msg; msg.m_client = &client; uint32_t m_nodeId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); DS::CryptRecvBuffer(client.m_sock, client.m_crypt, &msg.m_revision.m_bytes, sizeof(msg.m_revision.m_bytes)); uint32_t nodeSize = DS::CryptRecvSize(client.m_sock, client.m_crypt, NODE_SIZE_MAX); std::unique_ptr<uint8_t[]> nodeBuffer(new uint8_t[nodeSize]); DS::CryptRecvBuffer(client.m_sock, client.m_crypt, nodeBuffer.get(), nodeSize); DS::Blob nodeData = DS::Blob::Steal(nodeBuffer.release(), nodeSize); DS::BlobStream nodeStream(nodeData); msg.m_node.read(&nodeStream); DS_PASSERT(nodeStream.atEof()); msg.m_node.m_NodeIdx = m_nodeId; msg.m_internal = false; s_authChannel.putMessage(e_VaultUpdateNode, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); SEND_REPLY(); }
void cb_nodeTree(AuthServer_Private& client) { START_REPLY(e_AuthToCli_VaultNodeRefsFetched); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_NodeRefList msg; msg.m_client = &client; msg.m_nodeId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_VaultFetchNodeTree, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(0); } else { client.m_buffer.write<uint32_t>(msg.m_refs.size()); for (auto it = msg.m_refs.begin(); it != msg.m_refs.end(); ++it) { client.m_buffer.write<uint32_t>(it->m_parent); client.m_buffer.write<uint32_t>(it->m_child); client.m_buffer.write<uint32_t>(it->m_owner); client.m_buffer.write<uint8_t>(it->m_seen); } } SEND_REPLY(); }
void cb_nodeFind(AuthServer_Private& client) { START_REPLY(e_AuthToCli_VaultNodeFindReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_NodeFindList msg; msg.m_client = &client; uint32_t nodeSize = DS::CryptRecvSize(client.m_sock, client.m_crypt, NODE_SIZE_MAX); std::unique_ptr<uint8_t[]> nodeBuffer(new uint8_t[nodeSize]); DS::CryptRecvBuffer(client.m_sock, client.m_crypt, nodeBuffer.get(), nodeSize); DS::Blob nodeData = DS::Blob::Steal(nodeBuffer.release(), nodeSize); DS::BlobStream nodeStream(nodeData); msg.m_template.read(&nodeStream); DS_PASSERT(nodeStream.atEof()); s_authChannel.putMessage(e_VaultFindNode, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(0); } else { client.m_buffer.write<uint32_t>(msg.m_nodes.size()); for (size_t i=0; i<msg.m_nodes.size(); ++i) client.m_buffer.write<uint32_t>(msg.m_nodes[i]); } SEND_REPLY(); }
void cb_downloadNext(AuthServer_Private& client) { START_REPLY(e_AuthToCli_FileDownloadChunk); // Trans ID uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); client.m_buffer.write<uint32_t>(transId); auto fi = client.m_downloads.find(transId); if (fi == client.m_downloads.end()) { // The last chunk was already sent, we don't care anymore return; } client.m_buffer.write<uint32_t>(DS::e_NetSuccess); client.m_buffer.write<uint32_t>(fi->second->size()); client.m_buffer.write<uint32_t>(fi->second->tell()); uint8_t data[CHUNK_SIZE]; size_t bytesLeft = fi->second->size() - fi->second->tell(); if (bytesLeft > CHUNK_SIZE) { client.m_buffer.write<uint32_t>(CHUNK_SIZE); fi->second->readBytes(data, CHUNK_SIZE); client.m_buffer.writeBytes(data, CHUNK_SIZE); } else { client.m_buffer.write<uint32_t>(bytesLeft); fi->second->readBytes(data, bytesLeft); client.m_buffer.writeBytes(data, bytesLeft); delete fi->second; client.m_downloads.erase(fi); } SEND_REPLY(); }
void cb_scoreCreate(AuthServer_Private& client) { START_REPLY(e_AuthToCli_ScoreCreateReply); // Trans ID uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); client.m_buffer.write<uint32_t>(transId); Auth_CreateScore msg; msg.m_client = &client; msg.m_owner = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); msg.m_name = DS::CryptRecvString(client.m_sock, client.m_crypt); msg.m_type = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); msg.m_points = DS::CryptRecvValue<int32_t>(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_AuthCreateScore, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(0); // Score ID client.m_buffer.write<uint32_t>(0); // Create Time } else { client.m_buffer.write<uint32_t>(msg.m_scoreId); client.m_buffer.write<uint32_t>((uint32_t)time(0)); // close enough. } SEND_REPLY(); }
void cb_nodeFetch(AuthServer_Private& client) { START_REPLY(e_AuthToCli_VaultNodeFetched); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_NodeInfo msg; msg.m_client = &client; msg.m_node.set_NodeIdx(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); s_authChannel.putMessage(e_VaultFetchNode, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(0); } else { uint32_t sizePos = client.m_buffer.tell(); client.m_buffer.write<uint32_t>(0); msg.m_node.write(&client.m_buffer); uint32_t endPos = client.m_buffer.tell(); client.m_buffer.seek(sizePos, SEEK_SET); client.m_buffer.write<uint32_t>(endPos - sizePos - sizeof(uint32_t)); } SEND_REPLY(); }
void cb_downloadStart(FileServer_Private& client) { START_REPLY(e_FileToCli_FileDownloadReply); // Trans ID client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock)); // Download filename char16_t buffer[260]; DS::RecvBuffer(client.m_sock, buffer, sizeof(buffer)); buffer[259] = 0; DS::String filename = DS::String::FromUtf16(buffer); // Build ID uint32_t buildId = DS::RecvValue<uint32_t>(client.m_sock); if (buildId && buildId != DS::Settings::BuildId()) { fprintf(stderr, "[File] Wrong Build ID from %s: %d\n", DS::SockIpAddress(client.m_sock).c_str(), buildId); DS::CloseSock(client.m_sock); return; } // Ensure filename is jailed to our data path if (filename.find("..") != -1) { client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // Reader ID client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); return; } filename.replace("\\", "/"); filename = DS::Settings::FileRoot() + filename; int fd = open(filename.c_str(), O_RDONLY); if (fd < 0) { fprintf(stderr, "[File] Could not open file %s\n[File] Requested by %s\n", filename.c_str(), DS::SockIpAddress(client.m_sock).c_str()); client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // Reader ID client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); return; } std::unique_ptr<FileRequest> req(new FileRequest(fd)); client.m_buffer.write<uint32_t>(DS::e_NetSuccess); client.m_buffer.write<uint32_t>(++client.m_readerId); client.m_buffer.write<uint32_t>(req->m_size); FileRequest::chunk_t c = req->nextChunk(); client.m_buffer.write<uint32_t>(std::get<1>(c)); SEND_FD_REPLY(req->m_fd, req->m_pos, std::get<1>(c)); if (!std::get<0>(c)) { client.m_downloads[client.m_readerId] = std::move(req); } }
void cb_getPublicAges(AuthServer_Private& client) { START_REPLY(e_AuthToCli_PublicAgeList); // Trans ID uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); client.m_buffer.write<uint32_t>(transId); Auth_PubAgeRequest msg; msg.m_client = &client; msg.m_agename = DS::CryptRecvString(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_AuthGetPublic, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(0); } else { client.m_buffer.write<uint32_t>(msg.m_ages.size()); for (size_t i = 0; i < msg.m_ages.size(); i++) { client.m_buffer.writeBytes(msg.m_ages[i].m_instance.m_bytes, sizeof(client.m_acctUuid.m_bytes)); char16_t strbuffer[2048]; DS::StringBuffer<char16_t> buf; uint32_t copylen; buf = msg.m_agename.toUtf16(); copylen = buf.length() < 64 ? buf.length() : 63; memcpy(strbuffer, buf.data(), copylen * sizeof(char16_t)); strbuffer[copylen] = 0; client.m_buffer.writeBytes(strbuffer, 64 * sizeof(char16_t)); buf = msg.m_ages[i].m_instancename.toUtf16(); copylen = buf.length() < 64 ? buf.length() : 63; memcpy(strbuffer, buf.data(), copylen * sizeof(char16_t)); strbuffer[copylen] = 0; client.m_buffer.writeBytes(strbuffer, 64 * sizeof(char16_t)); buf = msg.m_ages[i].m_username.toUtf16(); copylen = buf.length() < 64 ? buf.length() : 63; memcpy(strbuffer, buf.data(), copylen * sizeof(char16_t)); strbuffer[copylen] = 0; client.m_buffer.writeBytes(strbuffer, 64 * sizeof(char16_t)); buf = msg.m_ages[i].m_description.toUtf16(); copylen = buf.length() < 1024 ? buf.length() : 1023; memcpy(strbuffer, buf.data(), copylen * sizeof(char16_t)); strbuffer[copylen] = 0; client.m_buffer.writeBytes(strbuffer, 1024 * sizeof(char16_t)); client.m_buffer.write<uint32_t>(msg.m_ages[i].m_sequence); client.m_buffer.write<uint32_t>(msg.m_ages[i].m_language); client.m_buffer.write<uint32_t>(msg.m_ages[i].m_population); client.m_buffer.write<uint32_t>(msg.m_ages[i].m_curPopulation); } } SEND_REPLY(); }
void cb_manifest(FileServer_Private& client) { START_REPLY(e_FileToCli_ManifestReply); // Trans ID client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock)); // Manifest name chr16_t mfsbuf[260]; DS::RecvBuffer(client.m_sock, mfsbuf, 260 * sizeof(chr16_t)); mfsbuf[259] = 0; DS::String mfsname = DS::String::FromUtf16(mfsbuf); // Build ID uint32_t buildId = DS::RecvValue<uint32_t>(client.m_sock); if (buildId && buildId != CLIENT_BUILD_ID) { fprintf(stderr, "[File] Wrong Build ID from %s: %d\n", DS::SockIpAddress(client.m_sock).c_str(), buildId); DS::CloseSock(client.m_sock); return; } // Manifest may not have any path characters if (mfsname.find(".") != -1 || mfsname.find("/") != -1 || mfsname.find("\\") != -1 || mfsname.find(":") != -1) { fprintf(stderr, "[File] Invalid manifest request from %s: %s\n", DS::SockIpAddress(client.m_sock).c_str(), mfsname.c_str()); client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // Reader ID client.m_buffer.write<uint32_t>(0); // File count client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); return; } DS::FileManifest manifest; mfsname = DS::Settings::FileRoot() + mfsname + ".mfs"; DS::NetResultCode result = manifest.loadManifest(mfsname.c_str()); client.m_buffer.write<uint32_t>(result); if (result != DS::e_NetSuccess) { fprintf(stderr, "[File] %s requested invalid manifest %s\n", DS::SockIpAddress(client.m_sock).c_str(), mfsname.c_str()); client.m_buffer.write<uint32_t>(0); // Reader ID client.m_buffer.write<uint32_t>(0); // File count client.m_buffer.write<uint32_t>(0); // Data packet size } else { client.m_buffer.write<uint32_t>(++client.m_readerId); client.m_buffer.write<uint32_t>(manifest.fileCount()); uint32_t sizeLocation = client.m_buffer.tell(); client.m_buffer.write<uint32_t>(0); uint32_t dataSize = manifest.encodeToStream(&client.m_buffer); client.m_buffer.seek(sizeLocation, SEEK_SET); client.m_buffer.write<uint32_t>(dataSize); } SEND_REPLY(); }
void cb_downloadStart(AuthServer_Private& client) { START_REPLY(e_AuthToCli_FileDownloadChunk); // Trans ID uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); client.m_buffer.write<uint32_t>(transId); // Download filename DS::String filename = DS::CryptRecvString(client.m_sock, client.m_crypt); // Ensure filename is jailed to our data path if (filename.find("..") != -1) { client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Chunk offset client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); return; } filename.replace("\\", "/"); filename = DS::Settings::AuthRoot() + filename; DS::FileStream* stream = new DS::FileStream(); try { stream->open(filename.c_str(), "rb"); } catch (const DS::FileIOException& ex) { fprintf(stderr, "[Auth] Could not open file %s: %s\n[Auth] Requested by %s\n", filename.c_str(), ex.what(), DS::SockIpAddress(client.m_sock).c_str()); client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Chunk offset client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); delete stream; return; } client.m_buffer.write<uint32_t>(DS::e_NetSuccess); client.m_buffer.write<uint32_t>(stream->size()); client.m_buffer.write<uint32_t>(stream->tell()); uint8_t data[CHUNK_SIZE]; if (stream->size() > CHUNK_SIZE) { client.m_buffer.write<uint32_t>(CHUNK_SIZE); stream->readBytes(data, CHUNK_SIZE); client.m_buffer.writeBytes(data, CHUNK_SIZE); client.m_downloads[transId] = stream; } else { client.m_buffer.write<uint32_t>(stream->size()); stream->readBytes(data, stream->size()); client.m_buffer.writeBytes(data, stream->size()); delete stream; } SEND_REPLY(); }
void cb_ping(FileServer_Private& client) { START_REPLY(e_FileToCli_PingReply); // Ping time client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock)); SEND_REPLY(); }
void cb_ping(GameClient_Private& client) { START_REPLY(e_GameToCli_PingReply); // Ping time client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); SEND_REPLY(); }
void cb_broadcast(AuthServer_Private& client) { DS::FifoMessage bcast = client.m_broadcast.getMessage(); DS::BufferStream* msg = reinterpret_cast<DS::BufferStream*>(bcast.m_payload); START_REPLY(bcast.m_messageType); client.m_buffer.writeBytes(msg->buffer(), msg->size()); msg->unref(); SEND_REPLY(); }
void cb_authServIpAddress(GateKeeper_Private& client) { START_REPLY(e_GateKeeperToCli_AuthServIpAddressReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); // Address ST::utf16_buffer address = DS::Settings::AuthServerAddress(); client.m_buffer.write<uint16_t>(address.size()); client.m_buffer.writeBytes(address.data(), address.size() * sizeof(char16_t)); SEND_REPLY(); }
void cb_buildId(FileServer_Private& client) { START_REPLY(e_FileToCli_BuildIdReply); // Trans ID client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock)); // Result client.m_buffer.write<uint32_t>(DS::e_NetSuccess); // Build ID client.m_buffer.write<uint32_t>(CLIENT_BUILD_ID); SEND_REPLY(); }
void cb_scoreGetScores(AuthServer_Private& client) { START_REPLY(e_AuthToCli_ScoreGetScoresReply); uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); client.m_buffer.write<uint32_t>(transId); Auth_GetScores msg; msg.m_client = &client; msg.m_owner = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); msg.m_name = DS::CryptRecvString(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_AuthGetScores, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); write_scoreBuffer(client, msg, reply); SEND_REPLY(); }
void cb_scoreSetPoints(AuthServer_Private& client) { START_REPLY(e_AuthToCli_ScoreSetPointsReply); uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); client.m_buffer.write<uint32_t>(transId); Auth_UpdateScore msg; msg.m_client = &client; msg.m_scoreId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); msg.m_points = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_AuthSetScorePoints, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); SEND_REPLY(); }
void cb_join(GameClient_Private& client) { START_REPLY(e_GameToCli_JoinAgeReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); uint32_t mcpId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); client.m_host = find_game_host(mcpId); DS_PASSERT(client.m_host != 0); Game_ClientMessage msg; msg.m_client = &client; DS::CryptRecvBuffer(client.m_sock, client.m_crypt, client.m_clientId.m_bytes, sizeof(client.m_clientId.m_bytes)); client.m_clientInfo.set_PlayerId(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); if (client.m_clientInfo.m_PlayerId == 0) { client.m_buffer.write<uint32_t>(DS::e_NetInvalidParameter); SEND_REPLY(); return; } // Get player info from the vault Auth_NodeInfo nodeInfo; nodeInfo.m_client = &client; nodeInfo.m_node.set_NodeIdx(client.m_clientInfo.m_PlayerId); s_authChannel.putMessage(e_VaultFetchNode, reinterpret_cast<void*>(&nodeInfo)); DS::FifoMessage reply = client.m_channel.getMessage(); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(reply.m_messageType); SEND_REPLY(); return; } msg.m_client->m_clientInfo.set_PlayerName(nodeInfo.m_node.m_IString64_1); msg.m_client->m_clientInfo.set_CCRLevel(0); client.m_host->m_channel.putMessage(e_GameJoinAge, reinterpret_cast<void*>(&msg)); reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); SEND_REPLY(); pthread_mutex_lock(&client.m_host->m_clientMutex); client.m_host->m_clients[client.m_clientInfo.m_PlayerId] = &client; pthread_mutex_unlock(&client.m_host->m_clientMutex); }
void cb_playerDelete(AuthServer_Private& client) { START_REPLY(e_AuthToCli_PlayerDeleteReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_PlayerDelete msg; msg.m_client = &client; msg.m_playerId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_AuthDeletePlayer, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); SEND_REPLY(); }
void cb_nodeUnref(AuthServer_Private& client) { START_REPLY(e_AuthToCli_VaultAddNodeReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_NodeRef msg; msg.m_client = &client; msg.m_ref.m_parent = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); msg.m_ref.m_child = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); s_authChannel.putMessage(e_VaultUnrefNode, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); SEND_REPLY(); }
void cb_fileList(AuthServer_Private& client) { START_REPLY(e_AuthToCli_FileListReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); DS::String directory = DS::CryptRecvString(client.m_sock, client.m_crypt); DS::String fileext = DS::CryptRecvString(client.m_sock, client.m_crypt); // Manifest may not have any path characters if (directory.find(".") != -1 || directory.find("/") != -1 || directory.find("\\") != -1 || directory.find(":") != -1 || fileext.find(".") != -1 || fileext.find("/") != -1 || fileext.find("\\") != -1 || fileext.find(":") != -1) { fprintf(stderr, "[Auth] Invalid manifest request from %s: %s\\%s\n", DS::SockIpAddress(client.m_sock).c_str(), directory.c_str(), fileext.c_str()); client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); return; } DS::String mfsname = DS::String::Format("%s%s_%s.list", DS::Settings::AuthRoot().c_str(), directory.c_str(), fileext.c_str()); DS::AuthManifest mfs; DS::NetResultCode result = mfs.loadManifest(mfsname.c_str()); client.m_buffer.write<uint32_t>(result); if (result != DS::e_NetSuccess) { fprintf(stderr, "[Auth] %s requested invalid manifest %s\n", DS::SockIpAddress(client.m_sock).c_str(), mfsname.c_str()); client.m_buffer.write<uint32_t>(0); // Data packet size } else { uint32_t sizeLocation = client.m_buffer.tell(); client.m_buffer.write<uint32_t>(0); uint32_t dataSize = mfs.encodeToStream(&client.m_buffer); client.m_buffer.seek(sizeLocation, SEEK_SET); client.m_buffer.write<uint32_t>(dataSize); } SEND_REPLY(); }
void cb_register(AuthServer_Private& client) { START_REPLY(e_AuthToCli_ClientRegisterReply); // Build ID uint32_t buildId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); if (buildId && buildId != DS::Settings::BuildId()) { fprintf(stderr, "[Auth] Wrong Build ID from %s: %d\n", DS::SockIpAddress(client.m_sock).c_str(), buildId); DS::CloseSock(client.m_sock); return; } // Client challenge RAND_bytes(reinterpret_cast<unsigned char*>(&client.m_serverChallenge), sizeof(client.m_serverChallenge)); client.m_buffer.write<uint32_t>(client.m_serverChallenge); SEND_REPLY(); }
void cb_ping(AuthServer_Private& client) { START_REPLY(e_AuthToCli_PingReply); // Ping time client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); // Payload uint32_t payloadSize = DS::CryptRecvSize(client.m_sock, client.m_crypt); client.m_buffer.write<uint32_t>(payloadSize); if (payloadSize) { std::unique_ptr<uint8_t[]> payload(new uint8_t[payloadSize]); DS::CryptRecvBuffer(client.m_sock, client.m_crypt, payload.get(), payloadSize); client.m_buffer.writeBytes(payload.get(), payloadSize); } SEND_REPLY(); }
void cb_setPlayer(AuthServer_Private& client) { START_REPLY(e_AuthToCli_AcctSetPlayerReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); // Player ID client.m_player.m_playerId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt); if (client.m_player.m_playerId == 0) { // No player -- always successful client.m_buffer.write<uint32_t>(DS::e_NetSuccess); } else { Auth_ClientMessage msg; msg.m_client = &client; s_authChannel.putMessage(e_AuthSetPlayer, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); } SEND_REPLY(); }
void cb_ageRequest(AuthServer_Private& client, bool ext) { START_REPLY(ext ? e_AuthToCli_AgeReplyEx : e_AuthToCli_AgeReply); // Trans ID client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt)); Auth_GameAge msg; msg.m_client = &client; msg.m_name = DS::CryptRecvString(client.m_sock, client.m_crypt); DS::CryptRecvBuffer(client.m_sock, client.m_crypt, &msg.m_instanceId.m_bytes, sizeof(msg.m_instanceId.m_bytes)); s_authChannel.putMessage(e_AuthFindGameServer, reinterpret_cast<void*>(&msg)); DS::FifoMessage reply = client.m_channel.getMessage(); client.m_buffer.write<uint32_t>(reply.m_messageType); if (reply.m_messageType != DS::e_NetSuccess) { client.m_buffer.write<uint32_t>(0); // MCP ID client.m_buffer.write<DS::Uuid>(DS::Uuid()); client.m_buffer.write<uint32_t>(0); // Age Node Idx // Game server address if (ext) client.m_buffer.write<uint16_t>(0); else client.m_buffer.write<uint32_t>(0); } else { client.m_buffer.write<uint32_t>(msg.m_mcpId); client.m_buffer.write<DS::Uuid>(msg.m_instanceId); client.m_buffer.write<uint32_t>(msg.m_ageNodeIdx); if (ext) client.m_buffer.writePString<uint16_t>(DS::Settings::GameServerAddress(), DS::e_StringUTF16); else client.m_buffer.write<uint32_t>(msg.m_serverAddress); } SEND_REPLY(); }
void cb_downloadNext(FileServer_Private& client) { START_REPLY(e_FileToCli_FileDownloadReply); uint32_t transId = DS::RecvValue<uint32_t>(client.m_sock); uint32_t readerId = DS::RecvValue<uint32_t>(client.m_sock); auto fi = client.m_downloads.find(readerId); if (fi == client.m_downloads.end()) { // The last chunk was already sent, we don't care anymore return; } client.m_buffer.write<uint32_t>(transId); client.m_buffer.write<uint32_t>(DS::e_NetSuccess); client.m_buffer.write<uint32_t>(fi->first); client.m_buffer.write<uint32_t>(fi->second->m_size); FileRequest::chunk_t c = fi->second->nextChunk(); client.m_buffer.write<uint32_t>(std::get<1>(c)); SEND_FD_REPLY(fi->second->m_fd, fi->second->m_pos, std::get<1>(c)); if (std::get<0>(c)) { client.m_downloads.erase(fi); } }
void cb_downloadStart(FileServer_Private& client) { START_REPLY(e_FileToCli_FileDownloadReply); // Trans ID client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock)); // Download filename chr16_t buffer[260]; DS::RecvBuffer(client.m_sock, buffer, 260 * sizeof(chr16_t)); buffer[259] = 0; DS::String filename = DS::String::FromUtf16(buffer); // Build ID uint32_t buildId = DS::RecvValue<uint32_t>(client.m_sock); if (buildId && buildId != CLIENT_BUILD_ID) { fprintf(stderr, "[File] Wrong Build ID from %s: %d\n", DS::SockIpAddress(client.m_sock).c_str(), buildId); DS::CloseSock(client.m_sock); return; } // Ensure filename is jailed to our data path if (filename.find("..") != -1) { client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // Reader ID client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); return; } filename.replace("\\", "/"); filename = DS::Settings::FileRoot() + filename; DS::FileStream* stream = new DS::FileStream(); try { stream->open(filename.c_str(), "rb"); } catch (DS::FileIOException ex) { fprintf(stderr, "[File] Could not open file %s: %s\n[File] Requested by %s\n", filename.c_str(), ex.what(), DS::SockIpAddress(client.m_sock).c_str()); client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound); client.m_buffer.write<uint32_t>(0); // Reader ID client.m_buffer.write<uint32_t>(0); // File size client.m_buffer.write<uint32_t>(0); // Data packet size SEND_REPLY(); delete stream; return; } client.m_buffer.write<uint32_t>(DS::e_NetSuccess); client.m_buffer.write<uint32_t>(++client.m_readerId); client.m_buffer.write<uint32_t>(stream->size()); uint8_t data[CHUNK_SIZE]; if (stream->size() > CHUNK_SIZE) { client.m_buffer.write<uint32_t>(CHUNK_SIZE); stream->readBytes(data, CHUNK_SIZE); client.m_buffer.writeBytes(data, CHUNK_SIZE); client.m_downloads[client.m_readerId] = stream; } else { client.m_buffer.write<uint32_t>(stream->size()); stream->readBytes(data, stream->size()); client.m_buffer.writeBytes(data, stream->size()); delete stream; } SEND_REPLY(); }