LifePlay-Revival/Source/LifePlay/LPStringCompat.h
edujiro5972 8015f182b9 L7i (CX-B12) : Contains/Split/FindSubstring avec motif vide au comportement 4.27 (385 noeuds, 28 Blueprints) ; ERR-005
FString::Find("" , IgnoreCase, FromStart) renvoie 0 en UE5 et INDEX_NONE en 4.27 : Contains(x, "") devenu vrai.
Test 3120 cas (transcription 4.27) : 0 ecart ; diff independant 385/385 ; compilation et cuisson 0 avertissement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 19:24:20 +02:00

55 lines
3.5 KiB
C++

// 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<FString> 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);
};