Cache real weather snapshots server side
This commit is contained in:
@@ -35,6 +35,12 @@ bool UAgrarianWeatherProviderSubsystem::RequestWeatherForTile(FName TileId, floa
|
||||
return false;
|
||||
}
|
||||
|
||||
AAgrarianGameState* GameState = World->GetGameState<AAgrarianGameState>();
|
||||
if (TryApplyCachedSnapshot(TileId, TEXT("open-meteo"), GameState))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const FString Url = BuildOpenMeteoForecastUrl(TileId, Latitude, Longitude);
|
||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
|
||||
Request->SetURL(Url);
|
||||
@@ -69,6 +75,12 @@ bool UAgrarianWeatherProviderSubsystem::RequestNoaaNwsFallbackForTile(FName Tile
|
||||
return false;
|
||||
}
|
||||
|
||||
AAgrarianGameState* GameState = World->GetGameState<AAgrarianGameState>();
|
||||
if (TryApplyCachedSnapshot(TileId, TEXT("noaa-nws"), GameState))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
|
||||
Request->SetURL(BuildNoaaNwsPointsUrl(Latitude, Longitude));
|
||||
Request->SetVerb(TEXT("GET"));
|
||||
@@ -108,6 +120,34 @@ bool UAgrarianWeatherProviderSubsystem::ApplySnapshotToGameState(const FAgrarian
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UAgrarianWeatherProviderSubsystem::TryApplyCachedSnapshot(FName TileId, const FString& Provider, AAgrarianGameState* GameState)
|
||||
{
|
||||
if (!GameState || !GameState->HasAuthority())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const FAgrarianCachedWeatherSnapshot* CachedSnapshot = ServerWeatherSnapshotCache.Find(MakeCacheKey(TileId, Provider));
|
||||
if (!CachedSnapshot || !CachedSnapshot->IsFresh(FDateTime::UtcNow()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LastSnapshot = CachedSnapshot->Snapshot;
|
||||
return ApplySnapshotToGameState(CachedSnapshot->Snapshot, GameState);
|
||||
}
|
||||
|
||||
bool UAgrarianWeatherProviderSubsystem::HasFreshCachedSnapshot(FName TileId, const FString& Provider) const
|
||||
{
|
||||
const FAgrarianCachedWeatherSnapshot* CachedSnapshot = ServerWeatherSnapshotCache.Find(MakeCacheKey(TileId, Provider));
|
||||
return CachedSnapshot && CachedSnapshot->IsFresh(FDateTime::UtcNow());
|
||||
}
|
||||
|
||||
void UAgrarianWeatherProviderSubsystem::ClearWeatherSnapshotCache()
|
||||
{
|
||||
ServerWeatherSnapshotCache.Empty();
|
||||
}
|
||||
|
||||
EAgrarianWeatherType UAgrarianWeatherProviderSubsystem::MapOpenMeteoWeatherCode(int32 WeatherCode, float PrecipitationMm, float WindSpeedKmh)
|
||||
{
|
||||
if (WeatherCode >= 95 || WindSpeedKmh >= 55.0f)
|
||||
@@ -129,6 +169,25 @@ EAgrarianWeatherType UAgrarianWeatherProviderSubsystem::MapOpenMeteoWeatherCode(
|
||||
return EAgrarianWeatherType::Clear;
|
||||
}
|
||||
|
||||
FString UAgrarianWeatherProviderSubsystem::MakeCacheKey(FName TileId, const FString& Provider) const
|
||||
{
|
||||
return FString::Printf(TEXT("%s:%s"), *Provider.ToLower(), *TileId.ToString());
|
||||
}
|
||||
|
||||
void UAgrarianWeatherProviderSubsystem::CacheSnapshot(const FAgrarianWeatherProviderSnapshot& Snapshot, float TimeToLiveSeconds)
|
||||
{
|
||||
if (!Snapshot.bIsValid || Snapshot.TileId == NAME_None || Snapshot.Provider.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FAgrarianCachedWeatherSnapshot CachedSnapshot;
|
||||
CachedSnapshot.Snapshot = Snapshot;
|
||||
CachedSnapshot.CachedAtUtc = FDateTime::UtcNow();
|
||||
CachedSnapshot.TimeToLiveSeconds = FMath::Max(60.0f, TimeToLiveSeconds);
|
||||
ServerWeatherSnapshotCache.Add(MakeCacheKey(Snapshot.TileId, Snapshot.Provider), CachedSnapshot);
|
||||
}
|
||||
|
||||
void UAgrarianWeatherProviderSubsystem::OnOpenMeteoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful, FName TileId, float Latitude, float Longitude)
|
||||
{
|
||||
if (!bWasSuccessful || !Response.IsValid() || Response->GetResponseCode() < 200 || Response->GetResponseCode() >= 300)
|
||||
@@ -143,6 +202,7 @@ void UAgrarianWeatherProviderSubsystem::OnOpenMeteoResponse(FHttpRequestPtr Requ
|
||||
}
|
||||
|
||||
LastSnapshot = Snapshot;
|
||||
CacheSnapshot(Snapshot, WeatherSnapshotCacheTtlSeconds);
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
AAgrarianGameState* GameState = World ? World->GetGameState<AAgrarianGameState>() : nullptr;
|
||||
@@ -200,6 +260,7 @@ void UAgrarianWeatherProviderSubsystem::OnNoaaNwsGridDataResponse(FHttpRequestPt
|
||||
}
|
||||
|
||||
LastSnapshot = Snapshot;
|
||||
CacheSnapshot(Snapshot, WeatherSnapshotCacheTtlSeconds);
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
AAgrarianGameState* GameState = World ? World->GetGameState<AAgrarianGameState>() : nullptr;
|
||||
|
||||
Reference in New Issue
Block a user