Skip to content

Commit

Permalink
added UninstallUnavailableMods to both C++ and BP layers
Browse files Browse the repository at this point in the history
  • Loading branch information
Turupawn committed Jun 12, 2020
1 parent bbf01c7 commit ea6e15d
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2019 modio. All Rights Reserved.
// Released under MIT.

#include "AsyncRequest/ModioAsyncRequest_UninstallUnavailableMods.h"
#include "ModioUE4Utility.h"

FModioAsyncRequest_UninstallUnavailableMods::FModioAsyncRequest_UninstallUnavailableMods( FModioSubsystem *Modio, FModioGenericDelegate Delegate, int32 PendingCalls ) :
FModioAsyncRequest( Modio ),
ResponseDelegate( Delegate )
{
this->PendingCalls = PendingCalls;
}

TArray<int32> getInstalledMods()
{
TArray<int32> InstalledMods;
u32 installed_mods_count = modioGetAllInstalledModsCount();
ModioInstalledMod *modio_installed_mods = (ModioInstalledMod *)malloc(installed_mods_count * sizeof(*modio_installed_mods));
modioGetAllInstalledMods(modio_installed_mods);
for (u32 i = 0; i < installed_mods_count; i++)
{
InstalledMods.Add(modio_installed_mods[i].mod.id);
modioFreeInstalledMod(&modio_installed_mods[i]);
}
free(modio_installed_mods);
return InstalledMods;
}

void FModioAsyncRequest_UninstallUnavailableMods::Response(void *Object, ModioResponse ModioResponse, ModioMod *ModioMods, u32 ModioModsSize)
{
UE_LOG(LogTemp, Warning, TEXT("[mod.io] FModioAsyncRequest_UninstallUnavailableMods response returned"));
FModioAsyncRequest_UninstallUnavailableMods* ThisPointer = (FModioAsyncRequest_UninstallUnavailableMods*)Object;

ThisPointer->PendingCalls--;
for(int32 i=0; i<(int32)ModioModsSize; i++)
{
ThisPointer->AvailableMods.Push(ModioMods[i].id);
}

if(ThisPointer->PendingCalls == 0)
{
UE_LOG(LogTemp, Warning, TEXT("[mod.io] FModioAsyncRequest_UninstallUnavailableMods response returned"));
for(auto InstalledMod : getInstalledMods())
{
bool IsAvailable = false;
for(auto AvailableMod : ThisPointer->AvailableMods)
{
if(InstalledMod == AvailableMod)
IsAvailable = true;
}
if(!IsAvailable)
{
UE_LOG(LogTemp, Warning, TEXT("[mod.io] Mod %i is unavailable, will be uninstalled"), InstalledMod);
modioUninstallMod((u32)InstalledMod);
}else
{
UE_LOG(LogTemp, Warning, TEXT("[mod.io] Mod %i is available"), InstalledMod);
}
}
FModioResponse Response;
InitializeResponse( Response, ModioResponse );

ThisPointer->ResponseDelegate.ExecuteIfBound( Response );

ThisPointer->Done();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2019 modio. All Rights Reserved.
// Released under MIT.

#include "BlueprintCallbackProxies/CallbackProxy_UninstallUnavailableMods.h"
#include "ModioSubsystem.h"
#include "Engine/Engine.h"

UCallbackProxy_UninstallUnavailableMods::UCallbackProxy_UninstallUnavailableMods(const FObjectInitializer &ObjectInitializer)
: Super(ObjectInitializer)
{
}

UCallbackProxy_UninstallUnavailableMods *UCallbackProxy_UninstallUnavailableMods::UninstallUnavailableMods(UObject *WorldContext)
{
UCallbackProxy_UninstallUnavailableMods *Proxy = NewObject<UCallbackProxy_UninstallUnavailableMods>();
Proxy->SetFlags(RF_StrongRefOnFrame);
Proxy->WorldContextObject = WorldContext;
return Proxy;
}

void UCallbackProxy_UninstallUnavailableMods::Activate()
{
UWorld* World = GEngine->GetWorldFromContextObject( WorldContextObject, EGetWorldErrorMode::LogAndReturnNull );
FModioSubsystemPtr Modio = FModioSubsystem::Get( World );
if( Modio.IsValid() )
{
Modio->UninstallUnavailableMods( FModioGenericDelegate::CreateUObject( this, &UCallbackProxy_UninstallUnavailableMods::OnUninstallUnavailableModsDelegate ) );
}
else
{
// @todonow: Make something more pretty than this
FModioResponse Response;
OnFailure.Broadcast( Response );
}
}

void UCallbackProxy_UninstallUnavailableMods::OnUninstallUnavailableModsDelegate(FModioResponse Response)
{
if (Response.Code >= 200 && Response.Code < 300)
{
OnSuccess.Broadcast(Response);
}
else
{
OnFailure.Broadcast(Response);
}
}
36 changes: 36 additions & 0 deletions Source/modio/Private/ModioSubsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,42 @@ bool FModioSubsystem::UninstallMod(int32 ModId)
return modioUninstallMod((u32)ModId);
}

void FModioSubsystem::UninstallUnavailableMods(FModioGenericDelegate UninstallUnavailableModsDelegate)
{
UE_LOG(LogTemp, Warning, TEXT("[mod.io] Uninstalling unavailable mods"));
int32 ResponseLimit = 100;
int32 PendingCalls = 1 + (this->GetAllInstalledMods().Num() / ResponseLimit);
UE_LOG(LogTemp, Warning, TEXT("[mod.io] A total of %i calls will be made to the mod.io API"), PendingCalls);
FModioAsyncRequest_UninstallUnavailableMods *Request = new FModioAsyncRequest_UninstallUnavailableMods( this, UninstallUnavailableModsDelegate, PendingCalls );

ModioFilterCreator modio_filter_creator;
modioInitFilter(&modio_filter_creator);
int32 CurrentCallCount = 0;
TArray<int32> ModIds;
QueueAsyncTask( Request );
for(auto InstalledMod : this->GetAllInstalledMods())
{
ModIds.Push(InstalledMod.Mod.Id);
CurrentCallCount ++;
modioAddFilterInField(&modio_filter_creator, "id", toString(InstalledMod.Mod.Id).c_str());
if(CurrentCallCount % 100 == 0)
{
UE_LOG(LogTemp, Warning, TEXT("[mod.io] Calling modioGetAllMods"));
CurrentCallCount = 0;
modioGetAllMods(Request, modio_filter_creator, FModioAsyncRequest_UninstallUnavailableMods::Response);

modioFreeFilter(&modio_filter_creator);
modioInitFilter(&modio_filter_creator);
}
}
if(CurrentCallCount > 0)
{
UE_LOG(LogTemp, Warning, TEXT("[mod.io] Calling final modioGetAllMods"));
modioGetAllMods(Request, modio_filter_creator, FModioAsyncRequest_UninstallUnavailableMods::Response);
modioFreeFilter(&modio_filter_creator);
}
}

void onModDownload(u32 response_code, u32 mod_id)
{
FModioSubsystem::ModioOnModDownloadDelegate.ExecuteIfBound( (int32)response_code, (int32)mod_id );
Expand Down
20 changes: 20 additions & 0 deletions Source/modio/Private/ModioUE4Utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,24 @@ void SetupModioModfileCreator(FModioModfileCreator ModfileCreator, ModioModfileC
modioSetModfileCreatorChangelog(&modio_modfile_creator, TCHAR_TO_UTF8(*ModfileCreator.Changelog));
if (ModfileCreator.Filehash != "")
modioSetModfileCreatorFilehash(&modio_modfile_creator, TCHAR_TO_UTF8(*ModfileCreator.Filehash));
}

std::string toString(int32 number)
{
if (number == 0)
return "0";

if (number < 0)
return "-" + toString(-number);

std::string temp = "";
std::string returnvalue = "";
while (number > 0)
{
temp += number % 10 + 48;
number /= 10;
}
for (size_t i = 0; i < temp.length(); i++)
returnvalue += temp[temp.length() - i - 1];
return returnvalue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2019 modio. All Rights Reserved.
// Released under MIT.

#pragma once
#include "AsyncRequest/ModioAsyncRequest.h"
#include "Schemas/ModioResponse.h"
#include "Schemas/ModioMod.h"

/**
* Callback returned when all unavailable mods were uninstalled
* @param ModioResponse - Response from Modio backend
*/

class FModioAsyncRequest_UninstallUnavailableMods : public FModioAsyncRequest
{
public:
int32 PendingCalls;
TArray<int32> AvailableMods;

FModioAsyncRequest_UninstallUnavailableMods( FModioSubsystem *Modio, FModioGenericDelegate Delegate, int32 PendingCalls );

static void Response(void *Object, ModioResponse ModioResponse, ModioMod *ModioMods, u32 ModioModsSize);

private:
FModioGenericDelegate ResponseDelegate;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2019 modio. All Rights Reserved.
// Released under MIT.

#pragma once

#include "ModioUE4Utility.h"
#include "Customizables/ModioFilterCreator.h"
#include "Schemas/ModioResponse.h"
#include "Schemas/ModioMod.h"
#include "Net/OnlineBlueprintCallProxyBase.h"
#include "CallbackProxy_UninstallUnavailableMods.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(
FUninstallUnavailableModsResult,
FModioResponse,
Response);

UCLASS()
class MODIO_API UCallbackProxy_UninstallUnavailableMods : public UOnlineBlueprintCallProxyBase
{
GENERATED_UCLASS_BODY()

// The world context object in which this call is taking place
UPROPERTY()
UObject* WorldContextObject;

UPROPERTY(BlueprintAssignable)
FUninstallUnavailableModsResult OnSuccess;

UPROPERTY(BlueprintAssignable)
FUninstallUnavailableModsResult OnFailure;

UFUNCTION(BlueprintCallable, Category = "mod.io", meta = (BlueprintInternalUseOnly = "true", DefaultToSelf="WorldContext"))
static UCallbackProxy_UninstallUnavailableMods *UninstallUnavailableMods(UObject *WorldContext);

virtual void Activate() override;

virtual void OnUninstallUnavailableModsDelegate(FModioResponse Response);
};
3 changes: 3 additions & 0 deletions Source/modio/Public/ModioSubsystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "AsyncRequest/ModioAsyncRequest_GetUserModfiles.h"
#include "AsyncRequest/ModioAsyncRequest_GetUserRatings.h"
#include "AsyncRequest/ModioAsyncRequest_SubscribeToMod.h"
#include "AsyncRequest/ModioAsyncRequest_UninstallUnavailableMods.h"
#include "AsyncRequest/ModioAsyncRequest_UnsubscribeFromMod.h"
#include "AsyncRequest/ModioAsyncRequest_SteamAuth.h"
#include "AsyncRequest/ModioAsyncRequest_SubmitReport.h"
Expand Down Expand Up @@ -175,6 +176,8 @@ struct MODIO_API FModioSubsystem : public TSharedFromThis<FModioSubsystem, ESPMo
void DownloadSubscribedModfiles(bool UninstallUnsubscribed, FModioBooleanDelegate DownloadSubscribedModfilesDelegate);
/** Uninstalls a mod from local storage */
bool UninstallMod(int32 ModId);
/** Uninstall all deleted or hidden mods */
void UninstallUnavailableMods(FModioGenericDelegate UninstallUnavailableModsDelegate);

// Mod Subscription
/** Subscribes to the corresponding mod */
Expand Down
4 changes: 3 additions & 1 deletion Source/modio/Public/ModioUE4Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Customizables/ModioModEditor.h"
#include "Customizables/ModioModfileCreator.h"
#include "Customizables/ModioFilterCreator.h"
#include <string>

extern TArray<FModioMod> ConvertToTArrayMods(ModioMod* ModioMods, u32 ModsSize);
extern TArray<FModioModfile> ConvertToTArrayModfiles(ModioModfile* ModioModfiles, u32 ModfilesSize);
Expand All @@ -31,4 +32,5 @@ extern void SetupModioFilterPagination(int32 Limit, int32 Offset, ModioFilterCre
extern void SetupModioModFilterCreator(const FModioFilterCreator &FilterCreator, const TArray<FString> &ModTags, int32 Limit, int32 Offset, ModioFilterCreator& modio_filter_creator);
extern void SetupModioModCreator(FModioModCreator ModCreator, ModioModCreator& modio_mod_creator);
extern void SetupModioModEditor(FModioModEditor ModEditor, ModioModEditor& modio_mod_editor);
extern void SetupModioModfileCreator(FModioModfileCreator ModfileCreator, ModioModfileCreator& modio_modfile_creator);
extern void SetupModioModfileCreator(FModioModfileCreator ModfileCreator, ModioModfileCreator& modio_modfile_creator);
std::string toString(int32 number);

0 comments on commit ea6e15d

Please sign in to comment.