// Portage UE 5.5 (2026.9 beta) - correctif CX-B08 (ERR-027). // // UE 5.x a reecrit FString::ParseIntoArray sur UE::String::ParseTokens. Deux comportements // ont change par rapport a UE 4.27, sans aucun avertissement : // 1. chaine source vide, CullEmpty=false : UE4 renvoie [] ; UE5 renvoie [""] ; // 2. recherche du separateur : UE4 respecte la casse (FCString::Strstr) ; UE5 l'ignore. // // Le cas 1 casse generatePerson() sans argument : "()" donne Presets=[""], GeneratePerson // charge alors les 141 presets (suffixe "" + ".lpcharacter") et finit sur un corps legacy // jamais charge -> personnage invisible et devetu. // // ULPStringCompat::ParseIntoArray reproduit a l'identique l'algorithme 4.27 (Source 4.27, // Runtime/Core/Private/Containers/String.cpp, FString::ParseIntoArray). Ses parametres et // ses valeurs par defaut sont ceux de UKismetStringLibrary::ParseIntoArray, pour que la // commandlet LPFixParseIntoArray puisse rebrancher les noeuds existants sans perdre de liaison. // // Correctif CX-B12 (lot L7i) : FString::Find avec une sous-chaine VIDE, recherche insensible a la // casse depuis le debut (mode par defaut des noeuds Contains, Find Substring et Split) : // - UE 4.27 : FCString::Stristr cherche le caractere nul final et ne le trouve jamais -> INDEX_NONE ; // - UE 5.5 : TCString::Strnistr renvoie le debut de la chaine -> 0. // "Contains(x, "")" est donc faux en 4.27 et vrai en 5.5. Les autres modes (sensible a la casse, // depuis la fin) donnent le meme resultat dans les deux moteurs. Contains, FindSubstring et Split // ci-dessous reprennent les parametres des fonctions de UKismetStringLibrary et appliquent la regle 4.27. #pragma once #include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "LPStringCompat.generated.h" UCLASS() class LIFEPLAY_API ULPStringCompat : public UBlueprintFunctionLibrary { GENERATED_BODY() public: /** ParseIntoArray avec le comportement exact de UE 4.27 (voir en-tete du fichier). */ UFUNCTION(BlueprintPure, Category = "Utilities|String", meta = (DisplayName = "Parse Into Array (UE4)")) static TArray ParseIntoArray(const FString& SourceString, const FString& Delimiter = FString(TEXT(" ")), const bool CullEmptyStrings = true); /** FindSubstring avec le comportement de UE 4.27 pour une sous-chaine vide (voir en-tete). */ UFUNCTION(BlueprintPure, Category = "Utilities|String", meta = (DisplayName = "Find Substring (UE4)")) static int32 FindSubstring(const FString& SearchIn, const FString& Substring, bool bUseCase = false, bool bSearchFromEnd = false, int32 StartPosition = -1); /** Contains avec le comportement de UE 4.27 pour une sous-chaine vide (voir en-tete). */ UFUNCTION(BlueprintPure, Category = "Utilities|String", meta = (DisplayName = "Contains (UE4)")) static bool Contains(const FString& SearchIn, const FString& Substring, bool bUseCase = false, bool bSearchFromEnd = false); /** Split avec le comportement de UE 4.27 pour un separateur vide (voir en-tete). */ UFUNCTION(BlueprintPure, Category = "Utilities|String", meta = (DisplayName = "Split (UE4)")) static bool Split(const FString& SourceString, const FString& InStr, FString& LeftS, FString& RightS, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase, ESearchDir::Type SearchDir = ESearchDir::FromStart); /** FString::Find de UE 4.27 : seul ecart avec UE 5.5, la sous-chaine vide en mode insensible a la casse depuis le debut. */ static int32 FindUE4(const FString& Str, const FString& SubStr, ESearchCase::Type SearchCase, ESearchDir::Type SearchDir, int32 StartPosition = INDEX_NONE); };