// Converts a raw 160-bit SHA1 digest into a Java Hex representation // According to http://wiki.vg/wiki/index.php?title=Protocol_Encryption&oldid=2802 static void DigestToJava(byte a_Digest[20], AString & a_Out) { bool IsNegative = (a_Digest[0] >= 0x80); if (IsNegative) { // Two's complement: bool carry = true; // Add one to the whole number for (int i = 19; i >= 0; i--) { a_Digest[i] = ~a_Digest[i]; if (carry) { carry = (a_Digest[i] == 0xff); a_Digest[i]++; } } } a_Out.clear(); a_Out.reserve(40); for (int i = 0; i < 20; i++) { AppendPrintf(a_Out, "%02x", a_Digest[i]); } while ((a_Out.length() > 0) && (a_Out[0] == '0')) { a_Out.erase(0, 1); } if (IsNegative) { a_Out.insert(0, "-"); } }
bool cSocketThreads::cSocketThread::SendDataThroughSocket(cSocket & a_Socket, AString & a_Data) { // Send data in smaller chunks, so that the OS send buffers aren't overflown easily while (!a_Data.empty()) { size_t NumToSend = std::min(a_Data.size(), (size_t)1024); int Sent = a_Socket.Send(a_Data.data(), NumToSend); if (Sent < 0) { int Err = cSocket::GetLastError(); if (Err == cSocket::ErrWouldBlock) { // The OS send buffer is full, leave the outgoing data for the next time return true; } // An error has occured return false; } if (Sent == 0) { a_Socket.CloseSocket(); return true; } a_Data.erase(0, Sent); } return true; }
void cBrewingRecipes::ReloadRecipes(void) { ClearRecipes(); LOGD("Loading brewing recipes..."); std::ifstream f(BREWING_RECIPE_FILE, std::ios::in); if (!f.good()) { LOG("Could not open the brewing recipes file \"%s\". No brewing recipes are available.", BREWING_RECIPE_FILE); return; } unsigned int LineNum = 0; AString ParsingLine; while (std::getline(f, ParsingLine)) { LineNum++; // Remove comments from the line: size_t FirstCommentSymbol = ParsingLine.find('#'); if (FirstCommentSymbol != AString::npos) { ParsingLine.erase(ParsingLine.begin() += static_cast<long>(FirstCommentSymbol), ParsingLine.end()); } if (ParsingLine.empty()) { continue; } AddRecipeFromLine(ParsingLine, LineNum); } // while (getline(ParsingLine)) LOG("Loaded " SIZE_T_FMT " brewing recipes", m_pState->Recipes.size()); }
void cSHA1Checksum::DigestToJava(const Checksum & a_Digest, AString & a_Out) { Checksum Digest; memcpy(Digest, a_Digest, sizeof(Digest)); bool IsNegative = (Digest[0] >= 0x80); if (IsNegative) { // Two's complement: bool carry = true; // Add one to the whole number for (int i = 19; i >= 0; i--) { Digest[i] = ~Digest[i]; if (carry) { carry = (Digest[i] == 0xff); Digest[i]++; } } } a_Out.clear(); a_Out.reserve(40); for (int i = 0; i < 20; i++) { AppendPrintf(a_Out, "%02x", Digest[i]); } while ((a_Out.length() > 0) && (a_Out[0] == '0')) { a_Out.erase(0, 1); } if (IsNegative) { a_Out.insert(0, "-"); } }
bool ARTSPConnection::receiveRTSPRequest() { AString requestLine; LOGI(LOG_TAG,"start receiveLine ......\n"); if (!receiveLine(&requestLine)) { return false; } // LOGI(LOG_TAG,"receiveLine OK\n"); sp<AMessage> request = new AMessage(kWhatRequest,mhandlerID); request->setInt32("SessionID",mSessionID); LOGI(LOG_TAG,"request->setInt32 SessionID %d\n",mSessionID); LOGI(LOG_TAG,"request: %s\n", requestLine.c_str()); ssize_t space1 = requestLine.find(" ");//寻找空格 if (space1 < 0) { return false; } ssize_t space2 = requestLine.find(" ", space1 + 1); if (space2 < 0) { return false; } AString Method(requestLine.c_str(), space1); request->setString("Method",Method.c_str()); AString URI(requestLine,space1+1,space2-space1-1); request->setString("URI",URI.c_str()); AString line; for (;;) { if (!receiveLine(&line)) { break; } if (line.empty()) { break; } ssize_t colonPos = line.find(":"); if (colonPos < 0) { // Malformed header line. return false; } AString key(line, 0, colonPos); key.trim(); // key.tolower(); line.erase(0, colonPos + 1); line.trim(); LOGI(LOG_TAG,"line: %s:%s\n", key.c_str(),line.c_str()); request->setString(key.c_str(),line.c_str()); } LOGI(LOG_TAG,"Post the request to handler\n"); request->post();//将请求消息发送给uplayer 处理 return OK; }
void cFurnaceRecipe::ReloadRecipes(void) { ClearRecipes(); LOGD("Loading furnace recipes..."); std::ifstream f(FURNACE_RECIPE_FILE, std::ios::in); if (!f.good()) { LOG("Could not open the furnace recipes file \"%s\". No furnace recipes are available.", FURNACE_RECIPE_FILE); return; } unsigned int LineNum = 0; AString ParsingLine; while (std::getline(f, ParsingLine)) { LineNum++; if (ParsingLine.empty()) { continue; } // Remove comments from the line: size_t FirstCommentSymbol = ParsingLine.find('#'); if ((FirstCommentSymbol != AString::npos) && (FirstCommentSymbol != 0)) { ParsingLine.erase(ParsingLine.begin() + static_cast<const long>(FirstCommentSymbol), ParsingLine.end()); } switch (ParsingLine[0]) { case '#': { // Comment break; } case '!': { AddFuelFromLine(ParsingLine, LineNum); break; } default: { AddRecipeFromLine(ParsingLine, LineNum); break; } } // switch (ParsingLine[0]) } // while (getline(ParsingLine)) LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); }
void cPlayer::KilledBy(cEntity * a_Killer) { super::KilledBy(a_Killer); if (m_Health > 0) { return; // not dead yet =] } m_bVisible = false; // So new clients don't see the player // Puke out all the items cItems Pickups; m_Inventory.CopyToItems(Pickups); m_Inventory.Clear(); if (GetName() == "Notch") { Pickups.Add(cItem(E_ITEM_RED_APPLE)); } m_Stats.AddValue(statItemsDropped, Pickups.Size()); m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); SaveToDisk(); // Save it, yeah the world is a tough place ! if (a_Killer == NULL) { GetWorld()->BroadcastChatDeath(Printf("%s was killed by environmental damage", GetName().c_str())); } else if (a_Killer->IsPlayer()) { cPlayer * Killer = (cPlayer *)a_Killer; GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), Killer->GetName().c_str())); } else { AString KillerClass = a_Killer->GetClass(); KillerClass.erase(KillerClass.begin()); // Erase the 'c' of the class (e.g. "cWitch" -> "Witch") GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str())); } m_Stats.AddValue(statDeaths); m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::otDeathCount, 1); }
AString GetOSErrorString( int a_ErrNo) { char buffer[ 1024 ]; AString Out; #ifdef _WIN32 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), NULL); Printf(Out, "%d: %s", a_ErrNo, buffer); if (!Out.empty() && (Out[Out.length() - 1] == '\n')) { Out.erase(Out.length() - 2); } return Out; #else // _WIN32 // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): #if !defined(__APPLE__) && ( _GNU_SOURCE) && !defined(ANDROID_NDK) // GNU version of strerror_r() char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer)); if (res != NULL) { Printf(Out, "%d: %s", a_ErrNo, res); return Out; } #else // XSI version of strerror_r(): int res = strerror_r( errno, buffer, ARRAYCOUNT(buffer)); if (res == 0) { Printf(Out, "%d: %s", a_ErrNo, buffer); return Out; } #endif // strerror_r() version else { Printf(Out, "Error %d while getting error string for error #%d!", errno, a_ErrNo); return Out; } #endif // else _WIN32 }
void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle) { if (a_AddStyle.empty()) { return; } if (a_AddStyle[0] == '@') { size_t idx = a_Style.find('@'); if ((idx != AString::npos) && (idx != a_Style.length())) { a_Style.erase(idx, 2); } a_Style.append(a_AddStyle); return; } a_Style.append(a_AddStyle); }
void cIniFile::RemoveBom(AString & a_line) const { // The BOM sequence for UTF-8 is 0xEF, 0xBB, 0xBF static unsigned const char BOM[] = { 0xEF, 0xBB, 0xBF }; // The BOM sequence, if present, is always th e first three characters of the input. const AString ref = a_line.substr(0, 3); // If any of the first three chars do not match, return and do nothing. for (size_t i = 0; i < 3; ++i) { if (static_cast<unsigned char>(ref[i]) != BOM[i]) { return; } } // First three characters match; erase them. a_line.erase(0, 3); }
void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID) { ASSERT(a_UUID.size() == 32); // Check if already present: { if (m_UUIDToProfile.find(a_UUID) != m_UUIDToProfile.end()) { return; } } // Create the request address: AString Address = m_UUIDToProfileAddress; ReplaceString(Address, "%UUID%", a_UUID); // Create the HTTP request: AString Request; Request += "GET " + Address + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding Request += "Host: " + m_UUIDToProfileServer + "\r\n"; Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; Request += "Content-Length: 0\r\n"; Request += "\r\n"; // Get the response from the server: AString Response; if (!SecureRequest(m_UUIDToProfileServer, Request, Response)) { return; } // Check the HTTP status line: const AString Prefix("HTTP/1.1 200 OK"); AString HexDump; if (Response.compare(0, Prefix.size(), Prefix)) { LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return; } // Erase the HTTP headers from the response: size_t idxHeadersEnd = Response.find("\r\n\r\n"); if (idxHeadersEnd == AString::npos) { LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return; } Response.erase(0, idxHeadersEnd + 4); // Parse the returned string into Json: Json::Reader reader; Json::Value root; if (!reader.parse(Response, root, false) || !root.isObject()) { LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return; } /* Example response: { "id": "b1caf24202a841a78055a079c460eee7", "name": "xoft", "properties": [ { "name": "textures", "value": "eyJ0aW1lc3RhbXAiOjE0MDcwNzAzMjEyNzEsInByb2ZpbGVJZCI6ImIxY2FmMjQyMDJhODQxYTc4MDU1YTA3OWM0NjBlZWU3IiwicHJvZmlsZU5hbWUiOiJ4b2Z0IiwiaXNQdWJsaWMiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9iNzc5YmFiZjVhNTg3Zjk0OGFkNjc0N2VhOTEyNzU0MjliNjg4Mjk1YWUzYzA3YmQwZTJmNWJmNGQwNTIifX19", "signature": "XCty+jGEF39hEPrPhYNnCX087kPaoCjYruzYI/DS4nkL5hbjnkSM5Rh15hnUyv/FHhC8OF5rif3D1tQjtMI19KSVaXoUFXpbJM8/+PB8GDgEbX8Fc3u9nYkzOcM/xfxdYsFAdFhLQMkvase/BZLSuPhdy9DdI+TCrO7xuSTZfYmmwVuWo3w5gCY+mSIAnqltnOzaOOTcly75xvO0WYpVk7nJdnR2tvSi0wfrQPDrIg/uzhX7p0SnDqijmBU4QaNez/TNKiFxy69dAzt0RSotlQzqkDbyVKhhv9a4eY8h3pXi4UMftKEj4FAKczxLImkukJXuOn5NN15/Q+le0rJVBC60/xjKIVzltEsMN6qjWD0lQjey7WEL+4pGhCVuWY5KzuZjFvgqszuJTFz7lo+bcHiceldJtea8/fa02eTRObZvdLxbWC9ZfFY0IhpOVKfcLdno/ddDMNMQMi5kMrJ8MZZ/PcW1w5n7MMGWPGCla1kOaC55AL0QYSMGRVEZqgU9wXI5M7sHGZKGM4mWxkbEJYBkpI/p3GyxWgV6v33ZWlsz65TqlNrR1gCLaoFCm7Sif8NqPBZUAONHYon0roXhin/DyEanS93WV6i6FC1Wisscjq2AcvnOlgTo/5nN/1QsMbjNumuMGo37sqjRqlXoPb8zEUbAhhztYuJjEfQ2Rd8=" } ] } */ // Store the returned result into caches: AString PlayerName = root.get("name", "").asString(); if (PlayerName.empty()) { // No valid playername, bail out return; } Json::Value Properties = root.get("properties", ""); Int64 Now = time(NULL); { cCSLock Lock(m_CSUUIDToProfile); m_UUIDToProfile[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now); } { cCSLock Lock(m_CSUUIDToName); m_UUIDToName[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now); } { cCSLock Lock(m_CSNameToUUID); m_NameToUUID[StrToLower(PlayerName)] = sProfile(PlayerName, a_UUID, Properties, Now); } }
void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) { // Create a list of names to query, by removing those that are already cached: AStringVector NamesToQuery; NamesToQuery.reserve(a_PlayerNames.size()); { cCSLock Lock(m_CSNameToUUID); for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) { if (m_NameToUUID.find(*itr) == m_NameToUUID.end()) { NamesToQuery.push_back(*itr); } } // for itr - a_PlayerNames[] } // Lock(m_CSNameToUUID) while (!NamesToQuery.empty()) { // Create the request body - a JSON containing up to MAX_PER_QUERY playernames: Json::Value root; int Count = 0; AStringVector::iterator itr = NamesToQuery.begin(), end = NamesToQuery.end(); for (; (itr != end) && (Count < MAX_PER_QUERY); ++itr, ++Count) { Json::Value req(*itr); root.append(req); } // for itr - a_PlayerNames[] NamesToQuery.erase(NamesToQuery.begin(), itr); Json::FastWriter Writer; AString RequestBody = Writer.write(root); // Create the HTTP request: AString Request; Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding Request += "Host: " + m_NameToUUIDServer + "\r\n"; Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; Request += "Content-Type: application/json\r\n"; Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length()); Request += "\r\n"; Request += RequestBody; // Get the response from the server: AString Response; if (!SecureRequest(m_NameToUUIDServer, Request, Response)) { continue; } // Check the HTTP status line: const AString Prefix("HTTP/1.1 200 OK"); AString HexDump; if (Response.compare(0, Prefix.size(), Prefix)) { LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } // Erase the HTTP headers from the response: size_t idxHeadersEnd = Response.find("\r\n\r\n"); if (idxHeadersEnd == AString::npos) { LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } Response.erase(0, idxHeadersEnd + 4); // Parse the returned string into Json: Json::Reader reader; if (!reader.parse(Response, root, false) || !root.isArray()) { LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } // Store the returned results into cache: size_t JsonCount = root.size(); Int64 Now = time(NULL); { cCSLock Lock(m_CSNameToUUID); for (size_t idx = 0; idx < JsonCount; ++idx) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; } m_NameToUUID[StrToLower(JsonName)] = sProfile(JsonName, JsonUUID, "", "", Now); } // for idx - root[] } // cCSLock (m_CSNameToUUID) // Also cache the UUIDToName: { cCSLock Lock(m_CSUUIDToName); for (size_t idx = 0; idx < JsonCount; ++idx) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; } m_UUIDToName[JsonUUID] = sProfile(JsonName, JsonUUID, "", "", Now); } // for idx - root[] } } // while (!NamesToQuery.empty()) }
bool ARTSPConnection::receiveRTSPReponse() { AString statusLine; if (!receiveLine(&statusLine)) { return false; } if (statusLine == "$") { sp<ABuffer> buffer = receiveBinaryData(); if (buffer == NULL) { return false; } if (mObserveBinaryMessage != NULL) { sp<AMessage> notify = mObserveBinaryMessage->dup(); notify->setBuffer("buffer", buffer); notify->post(); } else { ALOGW("received binary data, but no one cares."); } return true; } sp<ARTSPResponse> response = new ARTSPResponse; response->mStatusLine = statusLine; ALOGI("status: %s", response->mStatusLine.c_str()); ssize_t space1 = response->mStatusLine.find(" "); if (space1 < 0) { return false; } ssize_t space2 = response->mStatusLine.find(" ", space1 + 1); if (space2 < 0) { return false; } bool isRequest = false; if (!IsRTSPVersion(AString(response->mStatusLine, 0, space1))) { CHECK(IsRTSPVersion( AString( response->mStatusLine, space2 + 1, response->mStatusLine.size() - space2 - 1))); isRequest = true; response->mStatusCode = 0; } else { AString statusCodeStr( response->mStatusLine, space1 + 1, space2 - space1 - 1); if (!ParseSingleUnsignedLong( statusCodeStr.c_str(), &response->mStatusCode) || response->mStatusCode < 100 || response->mStatusCode > 999) { return false; } } AString line; ssize_t lastDictIndex = -1; for (;;) { if (!receiveLine(&line)) { break; } if (line.empty()) { break; } ALOGV("line: '%s'", line.c_str()); if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') { // Support for folded header values. if (lastDictIndex < 0) { // First line cannot be a continuation of the previous one. return false; } AString &value = response->mHeaders.editValueAt(lastDictIndex); value.append(line); continue; } ssize_t colonPos = line.find(":"); if (colonPos < 0) { // Malformed header line. return false; } AString key(line, 0, colonPos); key.trim(); key.tolower(); line.erase(0, colonPos + 1); lastDictIndex = response->mHeaders.add(key, line); } for (size_t i = 0; i < response->mHeaders.size(); ++i) { response->mHeaders.editValueAt(i).trim(); } unsigned long contentLength = 0; ssize_t i = response->mHeaders.indexOfKey("content-length"); if (i >= 0) { AString value = response->mHeaders.valueAt(i); if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) { return false; } } if (contentLength > 0) { response->mContent = new ABuffer(contentLength); if (receive(response->mContent->data(), contentLength) != OK) { return false; } } if (response->mStatusCode == 401) { if (mAuthType == NONE && mUser.size() > 0 && parseAuthMethod(response)) { ssize_t i; CHECK_EQ((status_t)OK, findPendingRequest(response, &i)); CHECK_GE(i, 0); sp<AMessage> reply = mPendingRequests.valueAt(i); mPendingRequests.removeItemsAt(i); AString request; CHECK(reply->findString("original-request", &request)); sp<AMessage> msg = new AMessage(kWhatSendRequest, id()); msg->setMessage("reply", reply); msg->setString("request", request.c_str(), request.size()); ALOGI("re-sending request with authentication headers..."); onSendRequest(msg); return true; } } return isRequest ? handleServerRequest(response) : notifyResponseListener(response); }
bool ARTSPConnection::receiveRTSPReponse() { AString statusLine; if (!receiveLine(&statusLine)) { return false; } if (statusLine == "$") { sp<ABuffer> buffer = receiveBinaryData(); if (buffer == NULL) { return false; } if (mObserveBinaryMessage != NULL) { sp<AMessage> notify = mObserveBinaryMessage->dup(); notify->setObject("buffer", buffer); notify->post(); } else { LOGW("received binary data, but no one cares."); } return true; } sp<ARTSPResponse> response = new ARTSPResponse; response->mStatusLine = statusLine; LOGI("status: %s", response->mStatusLine.c_str()); ssize_t space1 = response->mStatusLine.find(" "); if (space1 < 0) { return false; } ssize_t space2 = response->mStatusLine.find(" ", space1 + 1); if (space2 < 0) { return false; } AString statusCodeStr( response->mStatusLine, space1 + 1, space2 - space1 - 1); if (!ParseSingleUnsignedLong( statusCodeStr.c_str(), &response->mStatusCode) || response->mStatusCode < 100 || response->mStatusCode > 999) { return false; } AString line; for (;;) { if (!receiveLine(&line)) { break; } if (line.empty()) { break; } LOGV("line: %s", line.c_str()); ssize_t colonPos = line.find(":"); if (colonPos < 0) { // Malformed header line. return false; } AString key(line, 0, colonPos); key.trim(); key.tolower(); line.erase(0, colonPos + 1); line.trim(); response->mHeaders.add(key, line); } unsigned long contentLength = 0; ssize_t i = response->mHeaders.indexOfKey("content-length"); if (i >= 0) { AString value = response->mHeaders.valueAt(i); if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) { return false; } } if (contentLength > 0) { response->mContent = new ABuffer(contentLength); size_t numBytesRead = 0; while (numBytesRead < contentLength) { ssize_t n = recv( mSocket, response->mContent->data() + numBytesRead, contentLength - numBytesRead, 0); if (n == 0) { // Server closed the connection. TRESPASS(); } else if (n < 0) { if (errno == EINTR) { continue; } TRESPASS(); } numBytesRead += (size_t)n; } } return notifyResponseListener(response); }
void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatStart: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); AString iface; CHECK(msg->findString("iface", &iface)); status_t err = OK; ssize_t colonPos = iface.find(":"); unsigned long port; if (colonPos >= 0) { const char *s = iface.c_str() + colonPos + 1; char *end; port = strtoul(s, &end, 10); if (end == s || *end != '\0' || port > 65535) { err = -EINVAL; } else { iface.erase(colonPos, iface.size() - colonPos); } } else { port = kWifiDisplayDefaultPort; } if (err == OK) { if (inet_aton(iface.c_str(), &mInterfaceAddr) != 0) { sp<AMessage> notify = new AMessage(kWhatRTSPNotify, this); err = mNetSession->createRTSPServer( mInterfaceAddr, port, notify, &mSessionID); } else { err = -EINVAL; } } mState = AWAITING_CLIENT_CONNECTION; sp<AMessage> response = new AMessage; response->setInt32("err", err); response->postReply(replyID); break; } case kWhatRTSPNotify: { int32_t reason; CHECK(msg->findInt32("reason", &reason)); switch (reason) { case ANetworkSession::kWhatError: { int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); int32_t err; CHECK(msg->findInt32("err", &err)); AString detail; CHECK(msg->findString("detail", &detail)); ALOGE("An error occurred in session %d (%d, '%s/%s').", sessionID, err, detail.c_str(), strerror(-err)); mNetSession->destroySession(sessionID); if (sessionID == mClientSessionID) { mClientSessionID = 0; mClient->onDisplayError( IRemoteDisplayClient::kDisplayErrorUnknown); } break; } case ANetworkSession::kWhatClientConnected: { int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); if (mClientSessionID > 0) { ALOGW("A client tried to connect, but we already " "have one."); mNetSession->destroySession(sessionID); break; } CHECK_EQ(mState, AWAITING_CLIENT_CONNECTION); CHECK(msg->findString("client-ip", &mClientInfo.mRemoteIP)); CHECK(msg->findString("server-ip", &mClientInfo.mLocalIP)); if (mClientInfo.mRemoteIP == mClientInfo.mLocalIP) { // Disallow connections from the local interface // for security reasons. mNetSession->destroySession(sessionID); break; } CHECK(msg->findInt32( "server-port", &mClientInfo.mLocalPort)); mClientInfo.mPlaybackSessionID = -1; mClientSessionID = sessionID; ALOGI("We now have a client (%d) connected.", sessionID); mState = AWAITING_CLIENT_SETUP; status_t err = sendM1(sessionID); CHECK_EQ(err, (status_t)OK); break; } case ANetworkSession::kWhatData: { status_t err = onReceiveClientData(msg); if (err != OK) { mClient->onDisplayError( IRemoteDisplayClient::kDisplayErrorUnknown); } #if 0 // testing only. char val[PROPERTY_VALUE_MAX]; if (property_get("media.wfd.trigger", val, NULL)) { if (!strcasecmp(val, "pause") && mState == PLAYING) { mState = PLAYING_TO_PAUSED; sendTrigger(mClientSessionID, TRIGGER_PAUSE); } else if (!strcasecmp(val, "play") && mState == PAUSED) { mState = PAUSED_TO_PLAYING; sendTrigger(mClientSessionID, TRIGGER_PLAY); } } #endif break; } case ANetworkSession::kWhatNetworkStall: { break; } default: TRESPASS(); } break; } case kWhatStop: { CHECK(msg->senderAwaitsResponse(&mStopReplyID)); CHECK_LT(mState, AWAITING_CLIENT_TEARDOWN); if (mState >= AWAITING_CLIENT_PLAY) { // We have a session, i.e. a previous SETUP succeeded. status_t err = sendTrigger( mClientSessionID, TRIGGER_TEARDOWN); if (err == OK) { mState = AWAITING_CLIENT_TEARDOWN; (new AMessage(kWhatTeardownTriggerTimedOut, this))->post( kTeardownTriggerTimeouSecs * 1000000ll); break; } // fall through. } finishStop(); break; } case kWhatPause: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); status_t err = OK; if (mState != PLAYING) { err = INVALID_OPERATION; } else { mState = PLAYING_TO_PAUSED; sendTrigger(mClientSessionID, TRIGGER_PAUSE); } sp<AMessage> response = new AMessage; response->setInt32("err", err); response->postReply(replyID); break; } case kWhatResume: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); status_t err = OK; if (mState != PAUSED) { err = INVALID_OPERATION; } else { mState = PAUSED_TO_PLAYING; sendTrigger(mClientSessionID, TRIGGER_PLAY); } sp<AMessage> response = new AMessage; response->setInt32("err", err); response->postReply(replyID); break; } case kWhatReapDeadClients: { mReaperPending = false; if (mClientSessionID == 0 || mClientInfo.mPlaybackSession == NULL) { break; } if (mClientInfo.mPlaybackSession->getLastLifesignUs() + kPlaybackSessionTimeoutUs < ALooper::GetNowUs()) { ALOGI("playback session timed out, reaping."); mNetSession->destroySession(mClientSessionID); mClientSessionID = 0; mClient->onDisplayError( IRemoteDisplayClient::kDisplayErrorUnknown); } else { scheduleReaper(); } break; } case kWhatPlaybackSessionNotify: { int32_t playbackSessionID; CHECK(msg->findInt32("playbackSessionID", &playbackSessionID)); int32_t what; CHECK(msg->findInt32("what", &what)); if (what == PlaybackSession::kWhatSessionDead) { ALOGI("playback session wants to quit."); mClient->onDisplayError( IRemoteDisplayClient::kDisplayErrorUnknown); } else if (what == PlaybackSession::kWhatSessionEstablished) { mPlaybackSessionEstablished = true; if (mClient != NULL) { if (!mSinkSupportsVideo) { mClient->onDisplayConnected( NULL, // SurfaceTexture 0, // width, 0, // height, mUsingHDCP ? IRemoteDisplayClient::kDisplayFlagSecure : 0, 0); } else { size_t width, height; CHECK(VideoFormats::GetConfiguration( mChosenVideoResolutionType, mChosenVideoResolutionIndex, &width, &height, NULL /* framesPerSecond */, NULL /* interlaced */)); mClient->onDisplayConnected( mClientInfo.mPlaybackSession ->getSurfaceTexture(), width, height, mUsingHDCP ? IRemoteDisplayClient::kDisplayFlagSecure : 0, playbackSessionID); } } finishPlay(); if (mState == ABOUT_TO_PLAY) { mState = PLAYING; } } else if (what == PlaybackSession::kWhatSessionDestroyed) { disconnectClient2(); } else { CHECK_EQ(what, PlaybackSession::kWhatBinaryData); int32_t channel; CHECK(msg->findInt32("channel", &channel)); sp<ABuffer> data; CHECK(msg->findBuffer("data", &data)); CHECK_LE(channel, 0xff); CHECK_LE(data->size(), 0xffffu); int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); char header[4]; header[0] = '$'; header[1] = channel; header[2] = data->size() >> 8; header[3] = data->size() & 0xff; mNetSession->sendRequest( sessionID, header, sizeof(header)); mNetSession->sendRequest( sessionID, data->data(), data->size()); } break; } case kWhatKeepAlive: { int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); if (mClientSessionID != sessionID) { // Obsolete event, client is already gone. break; } sendM16(sessionID); break; } case kWhatTeardownTriggerTimedOut: { if (mState == AWAITING_CLIENT_TEARDOWN) { ALOGI("TEARDOWN trigger timed out, forcing disconnection."); CHECK(mStopReplyID != NULL); finishStop(); break; } break; } case kWhatHDCPNotify: { int32_t msgCode, ext1, ext2; CHECK(msg->findInt32("msg", &msgCode)); CHECK(msg->findInt32("ext1", &ext1)); CHECK(msg->findInt32("ext2", &ext2)); ALOGI("Saw HDCP notification code %d, ext1 %d, ext2 %d", msgCode, ext1, ext2); switch (msgCode) { case HDCPModule::HDCP_INITIALIZATION_COMPLETE: { mHDCPInitializationComplete = true; if (mSetupTriggerDeferred) { mSetupTriggerDeferred = false; sendTrigger(mClientSessionID, TRIGGER_SETUP); } break; } case HDCPModule::HDCP_SHUTDOWN_COMPLETE: case HDCPModule::HDCP_SHUTDOWN_FAILED: { // Ugly hack to make sure that the call to // HDCPObserver::notify is completely handled before // we clear the HDCP instance and unload the shared // library :( (new AMessage(kWhatFinishStop2, this))->post(300000ll); break; } default: { ALOGE("HDCP failure, shutting down."); mClient->onDisplayError( IRemoteDisplayClient::kDisplayErrorUnknown); break; } } break; } case kWhatFinishStop2: { finishStop2(); break; } default: TRESPASS(); } }
bool ARTSPConnection::receiveRTSPReponse() { AString statusLine; if (!receiveLine(&statusLine)) { return false; } if (statusLine == "$") { sp<ABuffer> buffer = receiveBinaryData(); if (buffer == NULL) { return false; } if (mObserveBinaryMessage != NULL) { sp<AMessage> notify = mObserveBinaryMessage->dup(); notify->setObject("buffer", buffer); notify->post(); } else { LOGW("received binary data, but no one cares."); } return true; } sp<ARTSPResponse> response = new ARTSPResponse; response->mStatusLine = statusLine; LOGI("status: %s", response->mStatusLine.c_str()); ssize_t space1 = response->mStatusLine.find(" "); if (space1 < 0) { return false; } ssize_t space2 = response->mStatusLine.find(" ", space1 + 1); if (space2 < 0) { return false; } AString statusCodeStr( response->mStatusLine, space1 + 1, space2 - space1 - 1); if (!ParseSingleUnsignedLong( statusCodeStr.c_str(), &response->mStatusCode) || response->mStatusCode < 100 || response->mStatusCode > 999) { return false; } AString line; for (;;) { if (!receiveLine(&line)) { break; } if (line.empty()) { break; } LOGV("line: %s", line.c_str()); ssize_t colonPos = line.find(":"); if (colonPos < 0) { // Malformed header line. return false; } AString key(line, 0, colonPos); key.trim(); key.tolower(); line.erase(0, colonPos + 1); line.trim(); response->mHeaders.add(key, line); } unsigned long contentLength = 0; ssize_t i = response->mHeaders.indexOfKey("content-length"); if (i >= 0) { AString value = response->mHeaders.valueAt(i); if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) { return false; } } if (contentLength > 0) { response->mContent = new ABuffer(contentLength); size_t numBytesRead = 0; while (numBytesRead < contentLength) { ssize_t n = recv( mSocket, response->mContent->data() + numBytesRead, contentLength - numBytesRead, 0); if (n == 0) { // Server closed the connection. TRESPASS(); } else if (n < 0) { if (errno == EINTR) { continue; } TRESPASS(); } numBytesRead += (size_t)n; } } if (response->mStatusCode == 401) { if (mAuthType == NONE && mUser.size() > 0 && parseAuthMethod(response)) { ssize_t i; CHECK_EQ((status_t)OK, findPendingRequest(response, &i)); CHECK_GE(i, 0); sp<AMessage> reply = mPendingRequests.valueAt(i); mPendingRequests.removeItemsAt(i); AString request; CHECK(reply->findString("original-request", &request)); sp<AMessage> msg = new AMessage(kWhatSendRequest, id()); msg->setMessage("reply", reply); msg->setString("request", request.c_str(), request.size()); LOGI("re-sending request with authentication headers..."); onSendRequest(msg); return true; } } return notifyResponseListener(response); }
bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID, Json::Value & a_Properties) { LOGD("Trying to authenticate user %s", a_UserName.c_str()); // Create the GET request: AString ActualAddress = m_Address; ReplaceString(ActualAddress, "%USERNAME%", a_UserName); ReplaceString(ActualAddress, "%SERVERID%", a_ServerId); AString Request; Request += "GET " + ActualAddress + " HTTP/1.0\r\n"; Request += "Host: " + m_Server + "\r\n"; Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; Request += "\r\n"; AString Response; if (!cMojangAPI::SecureRequest(m_Server, Request, Response)) { return false; } // Check the HTTP status line: const AString Prefix("HTTP/1.1 200 OK"); AString HexDump; if (Response.compare(0, Prefix.size(), Prefix)) { LOGINFO("User %s failed to auth, bad HTTP status line received", a_UserName.c_str()); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return false; } // Erase the HTTP headers from the response: size_t idxHeadersEnd = Response.find("\r\n\r\n"); if (idxHeadersEnd == AString::npos) { LOGINFO("User %s failed to authenticate, bad HTTP response header received", a_UserName.c_str()); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return false; } Response.erase(0, idxHeadersEnd + 4); // Parse the Json response: if (Response.empty()) { return false; } Json::Value root; Json::Reader reader; if (!reader.parse(Response, root, false)) { LOGWARNING("cAuthenticator: Cannot parse received data (authentication) to JSON!"); return false; } a_UserName = root.get("name", "Unknown").asString(); a_UUID = cMojangAPI::MakeUUIDShort(root.get("id", "").asString()); a_Properties = root["properties"]; // Store the player's profile in the MojangAPI caches: cRoot::Get()->GetMojangAPI().AddPlayerProfile(a_UserName, a_UUID, a_Properties); return true; }
bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID, Json::Value & a_Properties) { LOGD("Trying to authenticate user %s", a_UserName.c_str()); // Create the GET request: AString ActualAddress = m_Address; ReplaceString(ActualAddress, "%USERNAME%", a_UserName); ReplaceString(ActualAddress, "%SERVERID%", a_ServerId); AString Request; Request += "GET " + ActualAddress + " HTTP/1.0\r\n"; Request += "Host: " + m_Server + "\r\n"; Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; Request += "\r\n"; AString Response; if (!SecureGetFromAddress(StarfieldCACert(), m_Server, Request, Response)) { return false; } // Check the HTTP status line: const AString Prefix("HTTP/1.1 200 OK"); AString HexDump; if (Response.compare(0, Prefix.size(), Prefix)) { LOGINFO("User %s failed to auth, bad HTTP status line received", a_UserName.c_str()); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return false; } // Erase the HTTP headers from the response: size_t idxHeadersEnd = Response.find("\r\n\r\n"); if (idxHeadersEnd == AString::npos) { LOGINFO("User %s failed to authenticate, bad HTTP response header received", a_UserName.c_str()); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return false; } Response.erase(0, idxHeadersEnd + 4); // Parse the Json response: if (Response.empty()) { return false; } Json::Value root; Json::Reader reader; if (!reader.parse(Response, root, false)) { LOGWARNING("cAuthenticator: Cannot parse received data (authentication) to JSON!"); return false; } a_UserName = root.get("name", "Unknown").asString(); a_UUID = root.get("id", "").asString(); a_Properties = root["properties"]; // If the UUID doesn't contain the hashes, insert them at the proper places: if (a_UUID.size() == 32) { a_UUID.insert(8, "-"); a_UUID.insert(13, "-"); a_UUID.insert(18, "-"); a_UUID.insert(23, "-"); } return true; }
void cPlayer::KilledBy(TakeDamageInfo & a_TDI) { super::KilledBy(a_TDI); if (m_Health > 0) { return; // not dead yet =] } m_bVisible = false; // So new clients don't see the player // Puke out all the items cItems Pickups; m_Inventory.CopyToItems(Pickups); m_Inventory.Clear(); if (GetName() == "Notch") { Pickups.Add(cItem(E_ITEM_RED_APPLE)); } m_Stats.AddValue(statItemsDropped, (StatValue)Pickups.Size()); m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); SaveToDisk(); // Save it, yeah the world is a tough place ! if ((a_TDI.Attacker == NULL) && m_World->ShouldBroadcastDeathMessages()) { AString DamageText; switch (a_TDI.DamageType) { case dtRangedAttack: DamageText = "was shot"; break; case dtLightning: DamageText = "was plasmified by lightining"; break; case dtFalling: DamageText = (GetWorld()->GetTickRandomNumber(10) % 2 == 0) ? "fell to death" : "hit the ground too hard"; break; case dtDrowning: DamageText = "drowned"; break; case dtSuffocating: DamageText = (GetWorld()->GetTickRandomNumber(10) % 2 == 0) ? "git merge'd into a block" : "fused with a block"; break; case dtStarving: DamageText = "forgot the importance of food"; break; case dtCactusContact: DamageText = "was impaled on a cactus"; break; case dtLavaContact: DamageText = "was melted by lava"; break; case dtPoisoning: DamageText = "died from septicaemia"; break; case dtWithering: DamageText = "is a husk of their former selves"; break; case dtOnFire: DamageText = "forgot to stop, drop, and roll"; break; case dtFireContact: DamageText = "burnt themselves to death"; break; case dtInVoid: DamageText = "somehow fell out of the world"; break; case dtPotionOfHarming: DamageText = "was magicked to death"; break; case dtEnderPearl: DamageText = "misused an ender pearl"; break; case dtAdmin: DamageText = "was administrator'd"; break; case dtExplosion: DamageText = "blew up"; break; default: DamageText = "died, somehow; we've no idea how though"; break; } GetWorld()->BroadcastChatDeath(Printf("%s %s", GetName().c_str(), DamageText.c_str())); } else if (a_TDI.Attacker == NULL) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough { // no-op } else if (a_TDI.Attacker->IsPlayer()) { cPlayer * Killer = (cPlayer *)a_TDI.Attacker; GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), Killer->GetName().c_str())); } else { AString KillerClass = a_TDI.Attacker->GetClass(); KillerClass.erase(KillerClass.begin()); // Erase the 'c' of the class (e.g. "cWitch" -> "Witch") GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str())); } m_Stats.AddValue(statDeaths); m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::otDeathCount, 1); }