ParsedURL::ParsedURL(const String& urlString) { if (urlString.isEmpty()) { m_spec = URLString(); return; } // FIXME: handle invalid urlString. m_spec = URLString(urlString); if (urlString.is8Bit()) URLParser<LChar>::parseStandardURL(urlString.characters8(), urlString.length(), m_segments); else URLParser<UChar>::parseStandardURL(urlString.characters16(), urlString.length(), m_segments); }
ParsedURL::ParsedURL(const ParsedURL& base, const String& relative, URLQueryCharsetConverter* queryCharsetConverter) { if (!base.isValid()) return; unsigned relativeLength = relative.length(); if (!relativeLength) { *this = base.withoutFragment(); return; } RawURLBuffer<char> outputBuffer; const CString& baseStr = base.m_spec.m_string.utf8(); bool isValid = false; if (relative.is8Bit()) isValid = URLUtilities::resolveRelative(baseStr.data(), base.m_segments, reinterpret_cast<const char*>(relative.characters8()), relativeLength, queryCharsetConverter, outputBuffer, &m_segments); else isValid = URLUtilities::resolveRelative(baseStr.data(), base.m_segments, relative.characters16(), relativeLength, queryCharsetConverter, outputBuffer, &m_segments); if (isValid) m_spec = URLString(String(outputBuffer.data(), outputBuffer.length())); }
ParsedURL::ParsedURL(const String& urlString, URLQueryCharsetConverter* queryCharsetConverter) { unsigned urlStringLength = urlString.length(); if (!urlStringLength) return; RawURLBuffer<char> outputBuffer; String base; const CString& baseStr = base.utf8(); bool isValid = false; URLSegments baseSegments; // FIXME: we should take shortcuts here! We do not have to resolve the relative part. if (urlString.is8Bit()) isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments, reinterpret_cast<const char*>(urlString.characters8()), urlStringLength, queryCharsetConverter, outputBuffer, &m_segments); else isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments, urlString.characters16(), urlStringLength, queryCharsetConverter, outputBuffer, &m_segments); if (isValid) m_spec = URLString(String(outputBuffer.data(), outputBuffer.length())); }
ParsedURL::ParsedURL(const String& urlString, ParsedURLStringTag) { unsigned urlStringLength = urlString.length(); if (!urlStringLength) return; // FIXME: we should ASSERT on this, but people use KURL incorrectly with ParsedURLStringTag :(. RawURLBuffer<char> outputBuffer; String base; const CString& baseStr = base.utf8(); bool isValid = false; URLSegments baseSegments; // FIXME: we should take shortcuts here! We do not have to resolve the relative part. if (urlString.is8Bit()) isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments, reinterpret_cast<const char*>(urlString.characters8()), urlStringLength, /* charsetConverter */ 0, outputBuffer, &m_segments); else isValid = URLUtilities::resolveRelative(baseStr.data(), baseSegments, urlString.characters16(), urlStringLength, /* charsetConverter */ 0, outputBuffer, &m_segments); // FIXME: we should ASSERT on isValid, but people use KURL incorrectly with ParsedURLStringTag :(. if (isValid) m_spec = URLString(String(outputBuffer.data(), outputBuffer.length())); }
ParsedURL ParsedURL::isolatedCopy() const { ParsedURL copy; copy.m_segments = this->m_segments; copy.m_spec = URLString(this->m_spec.string().isolatedCopy()); return copy; }
ParsedURL ParsedURL::withoutFragment() const { if (!hasFragment()) return *this; ParsedURL newURL; int charactersBeforeFragemnt = m_segments.charactersBefore(URLSegments::Fragment, URLSegments::DelimiterExcluded); newURL.m_spec = URLString(m_spec.string().substringSharingImpl(0, charactersBeforeFragemnt)); newURL.m_segments = m_segments; newURL.m_segments.fragment = URLComponent(); return newURL; }
void ParsedURL::removePort() { if (!hasPort()) return; // 1) Remove the port from the spec, including the delimiter. String newSpec; int beginning = m_segments.port.begin() - 1; unsigned length = m_segments.port.length() + 1; String newSpecString = m_spec.string(); newSpecString.remove(beginning, length); m_spec = URLString(newSpecString); // 2) Update the components positions. m_segments.port.reset(); m_segments.moveFromComponentBy(URLSegments::Path, -length); }
ParsedURL::ParsedURL(const ParsedURL& base, const String& relative) { if (!base.isValid()) return; if (relative.isEmpty()) { *this = base.withoutFragment(); return; } // FIXME: handle invalid URLs. const String& baseString = base.m_spec.string(); RawURLBuffer<char, 1024> outputBuffer; if (relative.is8Bit()) { if (baseString.is8Bit()) { URLParser<LChar, LChar>::parseURLWithBase(relative.characters8(), relative.length(), baseString.characters8(), baseString.length(), base.m_segments, outputBuffer, m_segments); } else { URLParser<LChar, UChar>::parseURLWithBase(relative.characters8(), relative.length(), baseString.characters16(), baseString.length(), base.m_segments, outputBuffer, m_segments); } } else { if (baseString.is8Bit()) { URLParser<UChar, LChar>::parseURLWithBase(relative.characters16(), relative.length(), baseString.characters8(), baseString.length(), base.m_segments, outputBuffer, m_segments); } else { URLParser<UChar, UChar>::parseURLWithBase(relative.characters16(), relative.length(), baseString.characters16(), baseString.length(), base.m_segments, outputBuffer, m_segments); } } m_spec = URLString(String(outputBuffer.data(), outputBuffer.length())); }
void UPendingNetGame::NotifyControlMessage(UNetConnection* Connection, uint8 MessageType, class FInBunch& Bunch) { check(Connection==NetDriver->ServerConnection); #if !UE_BUILD_SHIPPING UE_LOG(LogNet, Verbose, TEXT("PendingLevel received: %s"), FNetControlMessageInfo::GetName(MessageType)); #endif // This client got a response from the server. switch (MessageType) { case NMT_Upgrade: // Report mismatch. uint32 RemoteNetworkVersion; FNetControlMessage<NMT_Upgrade>::Receive(Bunch, RemoteNetworkVersion); // Upgrade ConnectionError = NSLOCTEXT("Engine", "ClientOutdated", "The match you are trying to join is running an incompatible version of the game. Please try upgrading your game version.").ToString(); GEngine->BroadcastNetworkFailure(NULL, NetDriver, ENetworkFailure::OutdatedClient, ConnectionError); break; case NMT_Failure: { // our connection attempt failed for some reason, for example a synchronization mismatch (bad GUID, etc) or because the server rejected our join attempt (too many players, etc) // here we can further parse the string to determine the reason that the server closed our connection and present it to the user FString ErrorMsg; FNetControlMessage<NMT_Failure>::Receive(Bunch, ErrorMsg); if (ErrorMsg.IsEmpty()) { ErrorMsg = NSLOCTEXT("NetworkErrors", "GenericPendingConnectionFailed", "Pending Connection Failed.").ToString(); } // This error will be resolved in TickWorldTravel() ConnectionError = ErrorMsg; // Force close the session UE_LOG(LogNet, Log, TEXT("NetConnection::Close() [%s] [%s] [%s] from NMT_Failure %s"), Connection->Driver ? *Connection->Driver->NetDriverName.ToString() : TEXT("NULL"), Connection->PlayerController ? *Connection->PlayerController->GetName() : TEXT("NoPC"), Connection->OwningActor ? *Connection->OwningActor->GetName() : TEXT("No Owner"), *ConnectionError); Connection->Close(); break; } case NMT_Challenge: { // Challenged by server. FNetControlMessage<NMT_Challenge>::Receive(Bunch, Connection->Challenge); FURL PartialURL(URL); PartialURL.Host = TEXT(""); PartialURL.Port = PartialURL.UrlConfig.DefaultPort; // HACK: Need to fix URL parsing for (int32 i = URL.Op.Num() - 1; i >= 0; i--) { if (URL.Op[i].Left(5) == TEXT("game=")) { URL.Op.RemoveAt(i); } } FUniqueNetIdRepl UniqueIdRepl; ULocalPlayer* LocalPlayer = GEngine->GetFirstGamePlayer(this); if (LocalPlayer) { // Send the player nickname if available FString OverrideName = LocalPlayer->GetNickname(); if (OverrideName.Len() > 0) { PartialURL.AddOption(*FString::Printf(TEXT("Name=%s"), *OverrideName)); } // Send any game-specific url options for this player FString GameUrlOptions = LocalPlayer->GetGameLoginOptions(); if (GameUrlOptions.Len() > 0) { PartialURL.AddOption(*FString::Printf(TEXT("%s"), *GameUrlOptions)); } // Send the player unique Id at login UniqueIdRepl = LocalPlayer->GetPreferredUniqueNetId(); } Connection->ClientResponse = TEXT("0"); FString URLString(PartialURL.ToString()); FNetControlMessage<NMT_Login>::Send(Connection, Connection->ClientResponse, URLString, UniqueIdRepl); NetDriver->ServerConnection->FlushNet(); break; } case NMT_Welcome: { // Server accepted connection. FString GameName; FString RedirectURL; FNetControlMessage<NMT_Welcome>::Receive(Bunch, URL.Map, GameName, RedirectURL); //GEngine->NetworkRemapPath(this, URL.Map); UE_LOG(LogNet, Log, TEXT("Welcomed by server (Level: %s, Game: %s)"), *URL.Map, *GameName); // extract map name and options { FURL DefaultURL; FURL TempURL( &DefaultURL, *URL.Map, TRAVEL_Partial ); URL.Map = TempURL.Map; URL.RedirectURL = RedirectURL; URL.Op.Append(TempURL.Op); } if (GameName.Len() > 0) { URL.AddOption(*FString::Printf(TEXT("game=%s"), *GameName)); } // Send out netspeed now that we're connected FNetControlMessage<NMT_Netspeed>::Send(Connection, Connection->CurrentNetSpeed); // We have successfully connected. bSuccessfullyConnected = true; break; } case NMT_NetGUIDAssign: { FNetworkGUID NetGUID; FString Path; FNetControlMessage<NMT_NetGUIDAssign>::Receive(Bunch, NetGUID, Path); NetDriver->ServerConnection->PackageMap->ResolvePathAndAssignNetGUID(NetGUID, Path); break; } default: UE_LOG(LogNet, Log, TEXT(" --- Unknown/unexpected message for pending level")); break; } }