Compare commits
7 commits
master
...
GamejoltAP
Author | SHA1 | Date | |
---|---|---|---|
680e8fe41f | |||
d675f54f8c | |||
35db75963a | |||
61c533fcf7 | |||
6926c0ced8 | |||
b4b4dff00e | |||
e2a5cb9783 |
33 changed files with 1714 additions and 6 deletions
|
@ -5,7 +5,7 @@ DefaultGraphicsPerformance=Maximum
|
|||
AppliedDefaultGraphicsPerformance=Maximum
|
||||
|
||||
[/Script/EngineSettings.GameMapsSettings]
|
||||
EditorStartupMap=/Game/0_Project/Maps/TestTile.TestTile
|
||||
EditorStartupMap=/Game/0_Project/Maps/MainMap.MainMap
|
||||
LocalMapOptions=
|
||||
TransitionMap=None
|
||||
bUseSplitscreen=True
|
||||
|
@ -14,7 +14,7 @@ ThreePlayerSplitscreenLayout=FavorTop
|
|||
FourPlayerSplitscreenLayout=Grid
|
||||
bOffsetPlayerGamepadIds=False
|
||||
GameInstanceClass=/Game/0_Project/Core/Engine/MyGameInstance.MyGameInstance_C
|
||||
GameDefaultMap=/Game/0_Project/Maps/TestTile.TestTile
|
||||
GameDefaultMap=/Game/0_Project/Maps/MainMap.MainMap
|
||||
ServerDefaultMap=/Engine/Maps/Entry.Entry
|
||||
GlobalDefaultGameMode=/Game/0_Project/Core/Engine/My_GameMode.My_GameMode_C
|
||||
GlobalDefaultServerGameMode=None
|
||||
|
@ -31,13 +31,39 @@ r.DefaultFeature.AutoExposure=False
|
|||
[/Script/NavigationSystem.RecastNavMesh]
|
||||
bDoFullyAsyncNavDataGathering=False
|
||||
RuntimeGeneration=Dynamic
|
||||
DrawOffset=10.000000
|
||||
DrawOffset=1.000000
|
||||
bFixedTilePoolSize=False
|
||||
bSortNavigationAreasByCost=False
|
||||
CellSize=5.000000
|
||||
CellHeight=2.000000
|
||||
AgentRadius=10.000000
|
||||
AgentHeight=12.000000
|
||||
bForceRebuildOnLoad=True
|
||||
bAutoDestroyWhenNoNavigation=False
|
||||
ObservedPathsTickInterval=0.100000
|
||||
TilePoolSize=2048
|
||||
AgentMaxSlope=14.841908
|
||||
AgentMaxStepHeight=5.000000
|
||||
MinRegionArea=9.000000
|
||||
MergeRegionSize=50.000000
|
||||
bDrawPolyEdges=True
|
||||
MaxSimplificationError=1.500000
|
||||
TileSizeUU=300.000000
|
||||
|
||||
[/Script/NavigationSystem.NavigationSystemV1]
|
||||
bSpawnNavDataInNavBoundsLevel=False
|
||||
bGenerateNavigationOnlyAroundNavigationInvokers=False
|
||||
DirtyAreasUpdateFreq=2.000000
|
||||
DefaultAgentName=None
|
||||
CrowdManagerClass=/Script/AIModule.CrowdManager
|
||||
bAutoCreateNavigationData=True
|
||||
bSpawnNavDataInNavBoundsLevel=True
|
||||
bAllowClientSideNavigation=False
|
||||
bShouldDiscardSubLevelNavData=True
|
||||
bTickWhilePaused=True
|
||||
bInitialBuildingLocked=False
|
||||
bSkipAgentHeightCheckWhenPickingNavData=False
|
||||
DataGatheringMode=Instant
|
||||
bGenerateNavigationOnlyAroundNavigationInvokers=False
|
||||
ActiveTilesUpdateInterval=1.000000
|
||||
+SupportedAgents=(Name="Default",Color=(B=255,G=251,R=181,A=164),DefaultQueryExtent=(X=50.000000,Y=50.000000,Z=250.000000),NavDataClass=/Script/NavigationSystem.RecastNavMesh,AgentRadius=10.000000,AgentHeight=12.000000,AgentStepHeight=-1.000000,NavWalkingSearchHeightScale=0.500000,PreferredNavData=None,bCanCrouch=False,bCanJump=False,bCanWalk=True,bCanSwim=False,bCanFly=False)
|
||||
SupportedAgentsMask=(bSupportsAgent0=True,bSupportsAgent1=True,bSupportsAgent2=True,bSupportsAgent3=True,bSupportsAgent4=True,bSupportsAgent5=True,bSupportsAgent6=True,bSupportsAgent7=True,bSupportsAgent8=True,bSupportsAgent9=True,bSupportsAgent10=True,bSupportsAgent11=True,bSupportsAgent12=True,bSupportsAgent13=True,bSupportsAgent14=True,bSupportsAgent15=True)
|
||||
DirtyAreasUpdateFreq=0.100000
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/0_Project/Core/Engine/SPGameMode.uasset
Normal file
BIN
Content/0_Project/Core/Engine/SPGameMode.uasset
Normal file
Binary file not shown.
Binary file not shown.
BIN
Content/0_Project/Core/IA/SPBT.uasset
Normal file
BIN
Content/0_Project/Core/IA/SPBT.uasset
Normal file
Binary file not shown.
BIN
Content/0_Project/Core/IA/SPBlackboard.uasset
Normal file
BIN
Content/0_Project/Core/IA/SPBlackboard.uasset
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/0_Project/Core/Tiles/FirstTile.uasset
Normal file
BIN
Content/0_Project/Core/Tiles/FirstTile.uasset
Normal file
Binary file not shown.
BIN
Content/0_Project/Core/Tiles/Tile_Corner_A.uasset
Normal file
BIN
Content/0_Project/Core/Tiles/Tile_Corner_A.uasset
Normal file
Binary file not shown.
BIN
Content/0_Project/Core/Tiles/Tile_Corner_base.uasset
Normal file
BIN
Content/0_Project/Core/Tiles/Tile_Corner_base.uasset
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/0_Project/Maps/MainMenu.umap
Normal file
BIN
Content/0_Project/Maps/MainMenu.umap
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Plugins/GamejoltAPI/Binaries/Win64/UE4Editor-GameJoltPlugin.dll
Normal file
BIN
Plugins/GamejoltAPI/Binaries/Win64/UE4Editor-GameJoltPlugin.dll
Normal file
Binary file not shown.
BIN
Plugins/GamejoltAPI/Binaries/Win64/UE4Editor-GameJoltPlugin.pdb
Normal file
BIN
Plugins/GamejoltAPI/Binaries/Win64/UE4Editor-GameJoltPlugin.pdb
Normal file
Binary file not shown.
7
Plugins/GamejoltAPI/Binaries/Win64/UE4Editor.modules
Normal file
7
Plugins/GamejoltAPI/Binaries/Win64/UE4Editor.modules
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"BuildId": "13144385",
|
||||
"Modules":
|
||||
{
|
||||
"GameJoltPlugin": "UE4Editor-GameJoltPlugin.dll"
|
||||
}
|
||||
}
|
23
Plugins/GamejoltAPI/GameJoltPlugIn.uplugin
Normal file
23
Plugins/GamejoltAPI/GameJoltPlugIn.uplugin
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 14,
|
||||
"VersionName": "1.8",
|
||||
"FriendlyName": "GameJolt Plugin",
|
||||
"Description": " This plugin allows you to communicate with the GameJolt-Servers to use Scoreboards, Sessions, Cloud-Data-Storage and more.",
|
||||
"Category": "GameJolt",
|
||||
"CreatedBy": "FreezerNick",
|
||||
"CreatedByURL": "https://gamejolt.com/@FreezerNick",
|
||||
"DocsURL": "https://gitlab.com/f2p-entertainment/plugins/ue4/gj/ue4-gamejoltapi/-/wikis/home",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "mailto:incoming+f2p-entertainment-plugins-ue4-gj-ue4-gamejoltapi-5318268-issue-@incoming.gitlab.com",
|
||||
"EngineVersion": "4.25.0",
|
||||
"CanContainContent": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "GameJoltPlugin",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
]
|
||||
}
|
BIN
Plugins/GamejoltAPI/Resources/Icon128.png
Normal file
BIN
Plugins/GamejoltAPI/Resources/Icon128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
|
@ -0,0 +1,717 @@
|
|||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Interfaces/IHttpRequest.h"
|
||||
#include "Serialization/JsonSerializer.h"
|
||||
#include "Serialization/JsonWriter.h"
|
||||
#include "Dom/JsonValue.h"
|
||||
#include "UEGameJoltAPI.generated.h"
|
||||
|
||||
/* Represents all possible requests */
|
||||
UENUM(BlueprintType)
|
||||
enum class EGameJoltComponentEnum : uint8
|
||||
{
|
||||
GJ_USER_AUTH UMETA(DisplayName = "Authorize User"),
|
||||
GJ_USER_AUTOLOGIN UMETA(DisplayName = "Automatic Login"),
|
||||
GJ_USER_FETCH UMETA(DisplayName = "Fetch Current User"),
|
||||
GJ_USERS_FETCH UMETA(DisplayName = "Fetch Users"),
|
||||
GJ_USER_FRIENDLIST UMETA(DisplayName = "Fetch Friendlist"),
|
||||
GJ_SESSION_OPEN UMETA(DisplayName = "Open Session"),
|
||||
GJ_SESSION_PING UMETA(DisplayName = "Ping Session"),
|
||||
GJ_SESSION_CLOSE UMETA(DisplayName = "Close Session"),
|
||||
GJ_SESSION_CHECK UMETA(DisplayName = "Check Session"),
|
||||
GJ_TROPHIES_FETCH UMETA(DisplayName = "Fetch Trophies"),
|
||||
GJ_TROPHIES_ADD UMETA(DisplayName = "Reward Trophy"),
|
||||
GJ_TROHIES_REMOVE UMETA(DisplayName = "Remove Rewarded Trophy"),
|
||||
GJ_SCORES_FETCH UMETA(DisplayName = "Fetch Scores"),
|
||||
GJ_SCORES_ADD UMETA(DisplayName = "Add Score"),
|
||||
GJ_SCORES_TABLE UMETA(DisplayName = "Fetch Tables"),
|
||||
GJ_SCORES_RANK UMETA(DisplayName = "Fetch Rank of Highscore"),
|
||||
GJ_DATASTORE_FETCH UMETA(DisplayName = "Fetch Data"),
|
||||
GJ_DATASTORE_SET UMETA(DisplayName = "Set Data"),
|
||||
GJ_DATASTORE_UPDATE UMETA(DisplayName = "Update Data"),
|
||||
GJ_DATASTORE_REMOVE UMETA(DisplayName = "Fetch Keys"),
|
||||
GJ_OTHER UMETA(DisplayName = "Other"),
|
||||
GJ_TIME UMETA(DisplayName = "Fetch Server Time")
|
||||
};
|
||||
|
||||
/* Represents the possible selections for "Fetch Trophies" (all, achieved, unachieved) */
|
||||
UENUM(BlueprintType)
|
||||
enum class EGameJoltAchievedTrophies : uint8
|
||||
{
|
||||
GJ_ACHIEVEDTROPHY_BLANK UMETA(DisplayName = "All Trophies"),
|
||||
GJ_ACHIEVEDTROPHY_USER UMETA(DisplayName = "User Achieved Trophies"),
|
||||
GJ_ACHIEVEDTROPHY_GAME UMETA(DisplayName = "Unachieved Trophies")
|
||||
};
|
||||
|
||||
|
||||
/** Represents the possible values for the status of a session
|
||||
* https://gamejolt.com/game-api/doc/sessions/ping
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class ESessionStatus : uint8
|
||||
{
|
||||
Active,
|
||||
Idle
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EDataStore : uint8
|
||||
{
|
||||
Global,
|
||||
User
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EDataOperation : uint8
|
||||
{
|
||||
add UMETA(DisplayName = "Add"),
|
||||
substract UMETA(DisplayName = "Substract"),
|
||||
multiply UMETA(DisplayName = "Multiply"),
|
||||
divide UMETA(DisplayName = "Divide"),
|
||||
append UMETA(DisplayName = "Append"),
|
||||
prepend UMETA(DisplayName = "Prepend")
|
||||
};
|
||||
|
||||
/* Contains all available information about a user */
|
||||
USTRUCT(BlueprintType)
|
||||
struct FUserInfo
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "User ID")
|
||||
int32 S_User_ID;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "User type")
|
||||
FString User_Type;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Username")
|
||||
FString User_Name;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "User Avatar")
|
||||
FString User_AvatarURL;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "User Signed up")
|
||||
FString Signed_up;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "User Last Logged in")
|
||||
FString Last_Logged_in;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "User Status")
|
||||
FString status;
|
||||
};
|
||||
|
||||
/* Contains all information about a trophy */
|
||||
USTRUCT(BlueprintType)
|
||||
struct FTrophyInfo
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Trophy ID")
|
||||
int32 Trophy_ID;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Trophy's Name")
|
||||
FString Name;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Trophy's Description")
|
||||
FString Description;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Trophy's Difficulty")
|
||||
FString Difficulty;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Trophy's Image URL")
|
||||
FString image_url;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Achieved Time")
|
||||
FString achieved;
|
||||
};
|
||||
|
||||
/* Contains all information about an entry in a scoreboard */
|
||||
USTRUCT(BlueprintType)
|
||||
struct FScoreInfo
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString ScoreString;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
int32 ScoreSort;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString ExtraData;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString UserName;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
int32 UserID;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString Guest;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString UnixTimestamp;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
struct FDateTime TimeStamp;
|
||||
|
||||
FScoreInfo()
|
||||
{
|
||||
TimeStamp = FDateTime::Now();
|
||||
ScoreSort = 0;
|
||||
UserID = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* Contains all information about a scoreboard */
|
||||
USTRUCT(BlueprintType)
|
||||
struct FScoreTableInfo
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Scoreboard Table ID")
|
||||
int32 Id;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Scoreboard Table Name")
|
||||
FString Name;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Scoreboard Table Description")
|
||||
FString Description;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Scoreboard Table Primary")
|
||||
FString Primary;
|
||||
|
||||
};
|
||||
|
||||
/* Generates a delegate for the OnGetResult event */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnGetResult);
|
||||
|
||||
/* Generates a delegate for the OnFailed event */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnFailed);
|
||||
|
||||
#pragma region Specific Delegate Declaration
|
||||
|
||||
/* Authorize User */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnUserAuthorized, bool, bIsLoggedIn);
|
||||
/* Automatic Login */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAutoLogin, bool, bIsLoggedIn);
|
||||
/* Get Current User Info */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnUserFetched, FUserInfo, CurrentUserInfo);
|
||||
/* Get User Info*/
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnUsersFetched, const TArray<FUserInfo>&, UserInfo);
|
||||
/* Get Friendlist */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnFriendlistFetched, const TArray<int32>&, Friendlist);
|
||||
/* Open Session */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSessionOpened, bool, bIsSessionOpen);
|
||||
/* Ping Session */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSessionPinged, bool, bIsSessionStillOpen);
|
||||
/* Close Session */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSessionClosed, bool, bIsSessionClosed);
|
||||
/* Check Session */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSessionChecked, bool, bIsSessionStillOpen);
|
||||
/* Fetch Trophies */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTrophiesFetched, TArray<FTrophyInfo>, Trophies);
|
||||
/* Remove Trophy */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTrophyRemoved, bool, bWasRemoved);
|
||||
/* Add Score */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnScoreAdded, bool, bWasScoreAdded);
|
||||
/* Fetch Scoreboard */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnScoreboardFetched, const TArray<FScoreInfo>&, Scores);
|
||||
/* Fetch Scoreboard Table */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnScoreboardTableFetched, TArray<FScoreTableInfo>, ScoreboardTable);
|
||||
/* Fetch High-Score Rank */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnRankFetched, int32, Rank);
|
||||
/* Fetch Time */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTimeFetched, struct FDateTime, ServerTime);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/**
|
||||
* Class to use the GameJoltAPI
|
||||
* Is also internally used by an UUEGameJoltAPI instance as a carrier for response data
|
||||
*/
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class GAMEJOLTPLUGIN_API UUEGameJoltAPI : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Callback for IHttpRequest::OnProcessRequestComplete()
|
||||
* @param Request HTTP request pointer
|
||||
* @param Response Response pointer
|
||||
* @param bWasSuccessful Whether the request was successful or not
|
||||
*/
|
||||
void OnReady(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
|
||||
|
||||
/* Reset Data*/
|
||||
void Reset();
|
||||
|
||||
void WriteObject(TSharedRef<TJsonWriter<TCHAR>> writer, FString key, FJsonValue* value);
|
||||
|
||||
public:
|
||||
|
||||
UObject* contextObject;
|
||||
|
||||
/* Prevents crashes in Get-Functions */
|
||||
UPROPERTY(Transient)
|
||||
class UWorld* World;
|
||||
|
||||
/* Allows usage of the World-Property */
|
||||
virtual class UWorld* GetWorld() const override;
|
||||
|
||||
/* The username of the guest profile */
|
||||
UPROPERTY(BlueprintReadWrite, Category = "GameJolt|User")
|
||||
FString Guest_username;
|
||||
|
||||
/* Whether a user is currently logged in. Treated as a guest if false */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "GameJolt|User")
|
||||
bool bIsLoggedIn;
|
||||
|
||||
/* An enum representing the last request send. Local 'Get' nodes don't count */
|
||||
UPROPERTY(BlueprintReadWrite, Category = "GameJolt")
|
||||
EGameJoltComponentEnum LastActionPerformed;
|
||||
|
||||
/* The actual field data */
|
||||
TSharedPtr<FJsonObject> Data;
|
||||
|
||||
/* Contains the actual page content, as a string */
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "GameJolt|Request")
|
||||
FString Content;
|
||||
|
||||
/* Event which triggers when the content has been retrieved */
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events")
|
||||
FOnGetResult OnGetResult;
|
||||
|
||||
/* Event which triggers when the request failed */
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events")
|
||||
FOnFailed OnFailed;
|
||||
|
||||
#pragma region Specific Events
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnUserAuthorized OnUserAuthorized;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnAutoLogin OnAutoLogin;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnUserFetched OnUserFetched;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnUsersFetched OnUsersFetched;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnFriendlistFetched OnFriendlistFetched;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnSessionOpened OnSessionOpened;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnSessionPinged OnSessionPinged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnSessionClosed OnSessionClosed;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnSessionChecked OnSessionChecked;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnTrophiesFetched OnTrophiesFetched;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnTrophyRemoved OnTrophyRemoved;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnScoreAdded OnScoreAdded;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnScoreboardFetched OnScoreboardFetched;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnScoreboardTableFetched OnScoreboardTableFetched;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnRankFetched OnRankFetched;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "GameJolt|Events|Specific")
|
||||
FOnTimeFetched OnTimeFetched;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/* Creates new data from the input string */
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "From String"), Category = "GameJolt|Request")
|
||||
void FromString(const FString& dataString);
|
||||
|
||||
/**
|
||||
* Creates a new instance of the UUEGameJoltAPI class, for use in Blueprint graphs.
|
||||
* @param WorldContextObject The current context (default to self / this)
|
||||
* @return A pointer to the newly created post data
|
||||
**/
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Create GameJolt API Data", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "GameJolt")
|
||||
static UUEGameJoltAPI* Create(UObject* WorldContextObject);
|
||||
|
||||
/* GameID */
|
||||
UPROPERTY(BlueprintReadOnly, meta = (DisplayName = "Your Game ID"), Category = "GameJolt")
|
||||
int32 Game_ID;
|
||||
|
||||
/* Private Key */
|
||||
UPROPERTY(BlueprintReadOnly, meta = (DisplayName = "Your Game Private Key"), Category = "GameJolt")
|
||||
FString Game_PrivateKey;
|
||||
|
||||
/* Username */
|
||||
UPROPERTY(BlueprintReadOnly, meta = (DisplayName = "Players Username"), Category = "GameJolt|User")
|
||||
FString UserName;
|
||||
|
||||
private:
|
||||
/* Token */
|
||||
UPROPERTY()
|
||||
FString UserToken;
|
||||
|
||||
public:
|
||||
|
||||
/* Properties for HTTP-Request*/
|
||||
UPROPERTY(BlueprintReadWrite, meta = (DisplayName = "GameJolt API Server"), Category = "GameJolt|Request")
|
||||
FString GJAPI_SERVER;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, meta = (DisplayName = "GameJolt API Root"), Category = "GameJolt|Request")
|
||||
FString GJAPI_ROOT;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, meta = (DisplayName = "GameJolt API Version"), Category = "GameJolt|Request")
|
||||
FString GJAPI_VERSION;
|
||||
/* End of Properties */
|
||||
|
||||
/* Public Functions */
|
||||
|
||||
/**
|
||||
* Sets information needed for all requests
|
||||
* You can find these values in the GameJolt API section of your game's dashboard
|
||||
* @param PrivateKey The private key of your game
|
||||
* @param GameID The id of your game
|
||||
* @param AutoLogin Whether to check for passed credentials by the GameJolt client or not
|
||||
* @return Whether the .gj-crendential file was found or not. Also false if AutoLogin is false
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Init", AdvancedDisplay=2), Category = "GameJolt")
|
||||
bool Init(const int32 GameID, const FString PrivateKey, const bool AutoLogin);
|
||||
|
||||
private:
|
||||
|
||||
void AutoLogin(const FString Username, const FString Token);
|
||||
|
||||
|
||||
#pragma region Session
|
||||
|
||||
/**
|
||||
* Opens a session. You'll have to ping it manually with a timer
|
||||
* @return True if the request succeded, false if not
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DislayName = "Open Session"), Category = "GameJolt|Sessions")
|
||||
bool OpenSession();
|
||||
|
||||
/**
|
||||
* Pings the Session. Every 30 to 60 seconds is good.
|
||||
* @param SessionStatus The status of the session. Can be "Active" or "Idle"
|
||||
* @return True if the request succeded, false if not
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Ping Session"), Category = "GameJolt|Sessions")
|
||||
bool PingSession(ESessionStatus SessionStatus);
|
||||
|
||||
/**
|
||||
* Closes the session
|
||||
* @return True if the request succeded, false if not
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Close Session"), Category = "GameJolt|Sessions")
|
||||
bool CloseSession();
|
||||
|
||||
/**
|
||||
* Fetches the current session status
|
||||
* @return True if the request succeded, false if not
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Session Status"), Category = "GameJolt|Sessions")
|
||||
bool CheckSession();
|
||||
|
||||
/**
|
||||
* Gets the current session status
|
||||
* @return Whether the session is open or not. Also false if any error occurred
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Get Session Status"), Category = "GameJolt|Sessions")
|
||||
bool GetSessionStatus();
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/**
|
||||
* Gets the time of the GameJolt servers
|
||||
* @return True if the request succeded, false if not
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Server Time"), Category = "GameJolt|Misc")
|
||||
bool FetchServerTime();
|
||||
|
||||
/**
|
||||
* Puts the requested server time in a readable format
|
||||
* UUEGameJoltAPI::FetchServerTime has to be called before this function
|
||||
* @return The server time in a FDateTime struct
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Read Server Time"), Category = "GameJolt|Misc")
|
||||
struct FDateTime ReadServerTime();
|
||||
|
||||
#pragma region User
|
||||
|
||||
/**
|
||||
* Sends a request to authentificate the user
|
||||
* Call UUEGameJoltAPI::isUserAuthorize / Is User Login to check whether the authorization was successful or not
|
||||
* @param Name The username - case insensitive
|
||||
* @param Token The token - case insensitive
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Login"), Category = "GameJolt|User")
|
||||
void Login(const FString Name, const FString Token);
|
||||
|
||||
/**
|
||||
* Checks if the authentification was succesful
|
||||
* @return True if the user could be logged in, false if not
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Is User Login"), Category = "GameJolt|User")
|
||||
bool isUserAuthorize();
|
||||
|
||||
/* Resets user related properties */
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Logoff User"), Category = "GameJolt|User")
|
||||
void LogOffUser();
|
||||
|
||||
/**
|
||||
* Gets information about the current user
|
||||
* @return True if it the request succeded and false if it failed
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Current User Info"), Category = "GameJolt|User")
|
||||
bool FetchUser();
|
||||
|
||||
/**
|
||||
* Fetches an array of users
|
||||
* @param Users An array (int32) representing the user ids
|
||||
* @return True if the request succeded, false if not
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Users"), Category = "GameJolt|User")
|
||||
bool FetchUsers(const TArray<int32> Users);
|
||||
|
||||
/**
|
||||
* Gets a single or an array of users and puts them in an array of FUserInfo structs
|
||||
* @return An array with the FUserInfo structs
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Get User Info"), Category = "GameJolt|User")
|
||||
TArray<FUserInfo> GetUserInfo();
|
||||
|
||||
/**
|
||||
* Fetches the friendlist of the current user
|
||||
* @return True if the request could be send, false if not
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Friendlist"), Category = "GameJolt|User")
|
||||
bool FetchFriendlist();
|
||||
|
||||
/**
|
||||
* Returns the fetched friendlist
|
||||
* @warning Call FetchFriendlist first
|
||||
* @return The user ids of all friends
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Get Friendlist"), Category = "GameJolt|User")
|
||||
TArray<int32> GetFriendlist();
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Trophies
|
||||
|
||||
/**
|
||||
* Awards the current user a trophy
|
||||
* @return True if the request succeded, false if not
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Reward Trophies"), Category = "GameJolt|Trophies")
|
||||
bool RewardTrophy(const int32 Trophy_ID);
|
||||
|
||||
/**
|
||||
* Gets information for all trophies
|
||||
* This is meant for the use in Blueprints
|
||||
* It's just a wrapper around FetchTrophies with an empty TArray as an parameter
|
||||
* You can call UUEGameJoltAPI::FetchTrophies directly
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch All Trophies"), Category = "GameJolt|Trophies")
|
||||
void FetchAllTrophies(const EGameJoltAchievedTrophies AchievedType);
|
||||
|
||||
/**
|
||||
* Gets information for the selected trophies
|
||||
* @param AchievedType Whether only achieved, unachieved or all trophies should be fetched
|
||||
* @param Tropies_ID An array of trophy IDs. An empty array will return all trophies
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Trophies"), Category = "GameJolt|Trophies")
|
||||
void FetchTrophies(const EGameJoltAchievedTrophies AchievedType, const TArray<int32> Trophy_IDs);
|
||||
|
||||
/**
|
||||
* Gets the trophy information from the fetched trophies
|
||||
* @return Array of FTrophyInfo structs for all fetched trophies
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Get Trophies"), Category = "GameJolt|Trophies")
|
||||
TArray<FTrophyInfo> GetTrophies();
|
||||
|
||||
/**
|
||||
* Unachieved the specified trophy for the curernt user
|
||||
* @param Trophy_ID The ID of the trophy to be unachieved
|
||||
* @return Whether the request could be send or not
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Remove Rewarded Trophy"), Category = "GameJolt|Trophies")
|
||||
bool RemoveRewardedTrophy(const int32 Trophy_ID);
|
||||
|
||||
/**
|
||||
* Checks the success of a trophy removal
|
||||
* @return Whether the trophy was successfuly remove or not
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Check Trophy Removal Status"), Category = "GameJolt|Trophies")
|
||||
bool GetTrophyRemovalStatus();
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Scores
|
||||
|
||||
/**
|
||||
* Returns a list of scores either for a user or globally for a game
|
||||
* @param ScoreLimit The amount of scores you want to fetch. Default is 10, maximum is 100
|
||||
* @param Table_id The ID of the score table
|
||||
* @param BetterThan Fetch only scores better than this score sort value
|
||||
* @param WorseThan Fetch only scores worse than this score sort value
|
||||
* @return True if the request succeded, false if not
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Scoreboard"), Category = "GameJolt|Scoreboard")
|
||||
bool FetchScoreboard(const int32 ScoreLimit, const int32 Table_id, const int32 BetterThan, const int32 WorseThan);
|
||||
|
||||
/**
|
||||
* Gets the list of scores fetched with FetchScoreboard
|
||||
* @return An array of FScoreInfo structs for all entries
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Get Scoreboard"), Category = "GameJolt|Scoreboard")
|
||||
TArray<FScoreInfo> GetScoreboard();
|
||||
|
||||
/**
|
||||
* Adds an entry to a scoreboard
|
||||
* @param UserScore A String value associated with the score. Example: "234 Jumps".
|
||||
* @param UserScore_Sort An integer sorting value associated with the score. All sorting will work off of this number. Example: "234".
|
||||
* @param GuestUser The guest's name. Leave blank if you're storing for a user.
|
||||
* @param extra_data If there's any extra data you would like to store (as a string), you can use this variable. This data is never shown to the user.
|
||||
* @param table_id The id of the high score table that you want to submit to. If left blank the score will be submitted to the primary high score table.
|
||||
* @return True if the request succeded, false if not
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Score to Scoreboard"), Category = "GameJolt|Scoreboard")
|
||||
bool AddScore(const FString UserScore, const int32 UserScore_Sort, const FString GuestUser, const FString extra_data, const int32 table_id);
|
||||
|
||||
/**
|
||||
* Returns a list of high score tables for a game.
|
||||
* @return True if it the request succeded and false if it failed
|
||||
**/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Scoreboard Table"), Category = "GameJolt|Scoreboard")
|
||||
bool FetchScoreboardTable();
|
||||
|
||||
/**
|
||||
* Gets a list of high score tables for a game and puts them in an array of FScoreTableInfo structs
|
||||
* @return A array of FScoreTableInfo structs
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Get Scoreboard Table"), Category = "GameJolt|Scoreboard")
|
||||
TArray<FScoreTableInfo> GetScoreboardTable();
|
||||
|
||||
/**
|
||||
* Fetches the rank of the specified score
|
||||
* Use "Get Rank of Score" / GetRank or the OnGetRank delegate to read the results
|
||||
* @param Score The numeric score value to look for
|
||||
* @param TableID The ID of the scoreboard to search. '0' means primary table
|
||||
* @return Whether the request could be send successfully or not
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Fetch Rank of Score"), Category = "GameJolt|Scoreboard")
|
||||
bool FetchRank(const int32 Score, const int32 TableID);
|
||||
|
||||
/**
|
||||
* Gets the rank of a highscore from the response data
|
||||
*
|
||||
* If the score is not represented by any rank on the score table, the request will return the rank that is closest to the requested score.
|
||||
*
|
||||
* @warning Make sure to call "Fetch Rank of Score" / FetchRank before this
|
||||
* @return The rank of the score
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Rank of Score"), Category = "GameJolt|Scoreboard")
|
||||
int32 GetRank();
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Data-Store
|
||||
|
||||
/**
|
||||
* Either posts data for a new key or changes data for an existing one.
|
||||
* @param Type Whether to store the key/value pair for all users (global) or for the current user (user)
|
||||
* @param Key The key/label for the data
|
||||
* @param Data The actual data to store
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetData(EDataStore Type, const FString Key, const FString Data);
|
||||
|
||||
/**
|
||||
* Tries to fetch the data stored under the specified key
|
||||
* @param Type Whether to fetch a global key/value pair or a key/value pair stored for the current user
|
||||
* @param Key The key/label of the data
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void FetchData(EDataStore Type, FString Key);
|
||||
|
||||
/**
|
||||
* Updates already stored data
|
||||
* @param Type Whether to update a global key/value pair or a key/value pair stored of the current user
|
||||
* @param Key The key of the data to update
|
||||
* @param Operation The operation that should be performed on the data
|
||||
* @param Value The value for the selected operation
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void UpdateData(EDataStore Type, const FString Key, EDataOperation Operation, const FString Value);
|
||||
|
||||
/**
|
||||
* Deletes the data stored under the specified key
|
||||
* @param Type Whether to remove a global key/value pair or a key/value pair stored for the current user
|
||||
* @param Key The key of the data to remove
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void RemoveData(EDataStore Type, const FString Key);
|
||||
|
||||
/**
|
||||
* Gets the fetched data and converts them to a string or an integer (if possible)
|
||||
* @param Success Whether the data was found
|
||||
* @param DataAsString The fetched data as a string
|
||||
* @param DataAsInt The fetched data as an integer (0 if conversion was not possible)
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void GetData(bool& Success, FString& DataAsString, int32& DataAsInt);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Utility
|
||||
|
||||
/* Sends Request */
|
||||
UFUNCTION(Blueprintcallable, meta = (Displayname = " Send Request"), Category = "GameJolt|Request|Advanced")
|
||||
bool SendRequest(const FString& output, FString url, bool bAppendUserInfo = true);
|
||||
|
||||
/** Gets nested post data from the object with the specified key
|
||||
* @param key The key of the post data value
|
||||
* @return The value as an UUEGameJoltAPI object reference / pointer
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Data Field", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "GameJolt|Request|Advanced")
|
||||
UUEGameJoltAPI* GetObject(const FString& key);
|
||||
|
||||
/** Gets a string from the object with the specified key
|
||||
* @param key The key of the string value
|
||||
* @return The value as a string
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get String Field"), Category = "GameJolt|Request|Advanced")
|
||||
FString GetString(const FString& key) const;
|
||||
|
||||
/** Gets a bool from the object with the specified key
|
||||
* @param key The key of the bool value
|
||||
* @return The value as a bool
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Bool Field"), Category = "GameJolt|Request|Advanced")
|
||||
bool GetBool(const FString& key) const;
|
||||
|
||||
/** Gets an integer from the object with the specified key
|
||||
* @param key The key of the integer value
|
||||
* @return The value as an integer
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Int Field"), Category = "GameJolt|Request|Advanced")
|
||||
int32 GetInt(const FString& key) const;
|
||||
|
||||
/**
|
||||
* Gets a string array of all keys from the post data
|
||||
* @return An array with all keys
|
||||
*/
|
||||
UFUNCTION(Blueprintpure, meta = (Displayname = "Get Object Keys", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "GameJolt|Request|Advanced")
|
||||
TArray<FString> GetObjectKeys(UObject* WorldContextObject);
|
||||
|
||||
/**
|
||||
* Gets an array fromt the post data
|
||||
* @param key The key of the array
|
||||
* @return The array assigned to the key
|
||||
**/
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Object Array Field", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "GameJolt|Request|Advanced")
|
||||
TArray<UUEGameJoltAPI*> GetObjectArray(UObject* WorldContextObject, const FString& key);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
};
|
|
@ -0,0 +1,40 @@
|
|||
using UnrealBuildTool;
|
||||
using System.IO;
|
||||
|
||||
namespace UnrealBuildTool.Rules
|
||||
{
|
||||
public class GameJoltPlugin : ModuleRules
|
||||
{
|
||||
public GameJoltPlugin(ReadOnlyTargetRules Target) : base (Target)
|
||||
{
|
||||
|
||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Classes"));
|
||||
|
||||
PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Private"));
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"HTTP",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Json",
|
||||
}
|
||||
);
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Engine",
|
||||
"Core",
|
||||
"CoreUObject",
|
||||
"HTTP",
|
||||
"JSON",
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
#include "GameJoltPluginModule.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(GJAPI);
|
||||
|
||||
void GameJoltPlugin::StartupModule()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GameJoltPlugin::ShutdownModule()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IMPLEMENT_MODULE(FDefaultGameModuleImpl, GameJoltPlugin);
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(GJAPI, Log, All);
|
||||
|
||||
class GAMEJOLTPLUGIN_API GameJoltPlugin : public IModuleInterface
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
GameJoltPlugin();
|
||||
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
|
@ -0,0 +1,862 @@
|
|||
#include "UEGameJoltAPI.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "HttpModule.h"
|
||||
#include "Interfaces/IHttpResponse.h"
|
||||
#include "Dom/JsonObject.h"
|
||||
#include "Serialization/JsonReader.h"
|
||||
#include "GameJoltPluginModule.h"
|
||||
#include "Misc/DateTime.h"
|
||||
#include "Engine/World.h"
|
||||
#include "Misc/Paths.h"
|
||||
#include "Misc/FileHelper.h"
|
||||
|
||||
/* Constructor */
|
||||
UUEGameJoltAPI::UUEGameJoltAPI(const class FObjectInitializer& PCIP) : Super(PCIP)
|
||||
{
|
||||
Reset();
|
||||
bIsLoggedIn = false;
|
||||
GJAPI_SERVER = "api.gamejolt.com";
|
||||
GJAPI_ROOT = "/api/game/";
|
||||
GJAPI_VERSION = "v1_2";
|
||||
Game_ID = 0;
|
||||
Game_PrivateKey = "";
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_USER_AUTH;
|
||||
}
|
||||
|
||||
/* Prevents crashes within 'Get...' functions */
|
||||
UWorld* UUEGameJoltAPI::GetWorld() const
|
||||
{
|
||||
return World;
|
||||
}
|
||||
|
||||
/* Sets information needed for all requests */
|
||||
bool UUEGameJoltAPI::Init(const int32 GameID, const FString PrivateKey, const bool AutoLogin = false)
|
||||
{
|
||||
Game_ID = GameID;
|
||||
Game_PrivateKey = PrivateKey;
|
||||
if(!AutoLogin)
|
||||
{
|
||||
UE_LOG(GJAPI, Log, TEXT("Autologin is turned off!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!FPaths::FileExists(FPaths::Combine(FPaths::ProjectDir(), TEXT(".gj-credentials"))))
|
||||
return false;
|
||||
|
||||
TArray<FString> strings;
|
||||
FFileHelper::LoadFileToStringArray(strings, *FPaths::Combine(FPaths::ProjectDir(), TEXT(".gj-credentials")));
|
||||
this->AutoLogin(strings[1], strings[2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UUEGameJoltAPI::AutoLogin(const FString Name, const FString Token)
|
||||
{
|
||||
FString output;
|
||||
UserName = Name;
|
||||
UserToken = Token;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_USER_AUTOLOGIN;
|
||||
SendRequest(output, "/users/auth/?");
|
||||
}
|
||||
|
||||
/* Gets the time of the GameJolt servers */
|
||||
bool UUEGameJoltAPI::FetchServerTime()
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_TIME;
|
||||
return SendRequest(output, "/time/?", false);
|
||||
}
|
||||
|
||||
/* Puts the requested server time in a readable format */
|
||||
FDateTime UUEGameJoltAPI::ReadServerTime()
|
||||
{
|
||||
UUEGameJoltAPI* responseField = NULL;
|
||||
responseField = GetObject("response");
|
||||
if (responseField == NULL)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("responseField Return Null"));
|
||||
return FDateTime();
|
||||
}
|
||||
if(!responseField->GetBool("success"))
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Can't read time: Request failed!"));
|
||||
if(responseField->GetString("message") != "")
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Error message: %s"), *responseField->GetString("message"));
|
||||
}
|
||||
return FDateTime();
|
||||
}
|
||||
int32 Year = responseField->GetInt("year");
|
||||
int32 Month = responseField->GetInt("month");
|
||||
int32 Day = responseField->GetInt("day");
|
||||
int32 Hour = responseField->GetInt("hour");
|
||||
int32 Minute = responseField->GetInt("minute");
|
||||
int32 Second = responseField->GetInt("second");
|
||||
|
||||
return FDateTime(Year, Month, Day, Hour, Minute, Second);
|
||||
}
|
||||
|
||||
/* Creates a new instance of the UUEGameJoltAPI class, for use in Blueprint graphs. */
|
||||
UUEGameJoltAPI* UUEGameJoltAPI::Create(UObject* WorldContextObject) {
|
||||
// Get the world object from the context
|
||||
UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject);
|
||||
// Construct the object and return it
|
||||
UUEGameJoltAPI* fieldData = NewObject<UUEGameJoltAPI>((UUEGameJoltAPI*)GetTransientPackage(), UUEGameJoltAPI::StaticClass());
|
||||
fieldData->contextObject = WorldContextObject;
|
||||
fieldData->World = World;
|
||||
return fieldData;
|
||||
}
|
||||
|
||||
/* Sends a request to authentificate the user */
|
||||
void UUEGameJoltAPI::Login(const FString name, const FString token)
|
||||
{
|
||||
FString output;
|
||||
FString GameIDString = FString::FromInt(Game_ID);
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_USER_AUTH;
|
||||
UserName = name;
|
||||
UserToken = token;
|
||||
SendRequest(output, "/users/auth/?");
|
||||
}
|
||||
|
||||
/* Checks if the authentification was succesful */
|
||||
bool UUEGameJoltAPI::isUserAuthorize()
|
||||
{
|
||||
bool outAuthorize;
|
||||
UUEGameJoltAPI* responseField = NULL;
|
||||
responseField = GetObject("response");
|
||||
if (responseField == NULL)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("responseField Return Null"));
|
||||
return false;
|
||||
}
|
||||
outAuthorize = responseField->GetBool("success");
|
||||
if (!outAuthorize)
|
||||
{
|
||||
bIsLoggedIn = false;
|
||||
UE_LOG(GJAPI, Error, TEXT("Couldn't authenticate user. Message: %s"), *responseField->GetString("message"));
|
||||
return false;
|
||||
}
|
||||
|
||||
bIsLoggedIn = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Gets information the current user */
|
||||
bool UUEGameJoltAPI::FetchUser()
|
||||
{
|
||||
bool ret = false;
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_USER_FETCH;
|
||||
ret = SendRequest(output, "/users/?username=" + UserName, false);
|
||||
if (!ret)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Could not fetch user."));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Fetches an array of users */
|
||||
bool UUEGameJoltAPI::FetchUsers(const TArray<int32> Users)
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_USERS_FETCH;
|
||||
FString UserIDs = "";
|
||||
for(const int32 UserID : Users)
|
||||
UserIDs.Append(FString::FromInt(UserID) + ",");
|
||||
return SendRequest(output, "/users/?user_id=" + UserIDs, false);
|
||||
}
|
||||
|
||||
/* Fetches the friendlist of the current user */
|
||||
bool UUEGameJoltAPI::FetchFriendlist()
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_USER_FRIENDLIST;
|
||||
return SendRequest(output, "/friends/?");
|
||||
}
|
||||
|
||||
/* Gets the friendlist */
|
||||
TArray<int32> UUEGameJoltAPI::GetFriendlist()
|
||||
{
|
||||
TArray<UUEGameJoltAPI*> returnArray = GetObject("response")->GetObjectArray(GetObject("response"), "friends");
|
||||
TArray<int32> returnIDs;
|
||||
for(int i = 0; i < returnArray.Num(); i++)
|
||||
returnIDs.Add(returnArray[i]->GetInt("friend_id"));
|
||||
return returnIDs;
|
||||
}
|
||||
|
||||
/* Resets user related properties */
|
||||
void UUEGameJoltAPI::LogOffUser()
|
||||
{
|
||||
bIsLoggedIn = false;
|
||||
UserName = "";
|
||||
UserToken = "";
|
||||
}
|
||||
|
||||
/* Opens a session */
|
||||
bool UUEGameJoltAPI::OpenSession()
|
||||
{
|
||||
FString output;
|
||||
FString GameIDString;
|
||||
GameIDString = FString::FromInt(Game_ID);
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_SESSION_OPEN;
|
||||
return SendRequest(output, "/sessions/open/?");
|
||||
}
|
||||
|
||||
/* Pings the session */
|
||||
bool UUEGameJoltAPI::PingSession(ESessionStatus SessionStatus)
|
||||
{
|
||||
FString output;
|
||||
FString SessionString = SessionStatus == ESessionStatus::Active ? FString("active") : FString("idle");
|
||||
FString GameIDString = FString::FromInt(Game_ID);
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_SESSION_PING;
|
||||
return SendRequest(output, "/sessions/ping/?status=" + SessionString);
|
||||
}
|
||||
|
||||
/* Closes the session */
|
||||
bool UUEGameJoltAPI::CloseSession()
|
||||
{
|
||||
FString output;
|
||||
FString GameIDString;
|
||||
GameIDString = FString::FromInt(Game_ID);
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_SESSION_CLOSE;
|
||||
return SendRequest(output, "/sessions/close/?");
|
||||
}
|
||||
|
||||
/* Fetches the session status */
|
||||
bool UUEGameJoltAPI::CheckSession()
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_SESSION_CHECK;
|
||||
return SendRequest(output, "/sessions/check/?");
|
||||
}
|
||||
|
||||
/* Gets the session status */
|
||||
bool UUEGameJoltAPI::GetSessionStatus()
|
||||
{
|
||||
UUEGameJoltAPI* Response = GetObject("response");
|
||||
if(!Response)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Response invalid in GetSessionStatus. Was ist called to early?"));
|
||||
return false;
|
||||
}
|
||||
return Response->GetBool("success");
|
||||
}
|
||||
|
||||
/* Gets an array of users and puts them in an array of FUserInfo structs */
|
||||
TArray<FUserInfo> UUEGameJoltAPI::GetUserInfo()
|
||||
{
|
||||
TArray<UUEGameJoltAPI*> returnArray = GetObject("response")->GetObjectArray(GetObject("response"), "users");
|
||||
|
||||
TArray<FUserInfo> returnUserInfo;
|
||||
|
||||
FUserInfo tempUser;
|
||||
|
||||
for (int i = 0; i< returnArray.Num(); i++)
|
||||
{
|
||||
|
||||
tempUser.S_User_ID = returnArray[i]->GetInt("id");
|
||||
tempUser.User_Name = returnArray[i]->GetString("username");
|
||||
tempUser.User_Type = returnArray[i]->GetString("type");
|
||||
tempUser.User_AvatarURL = returnArray[i]->GetString("avatar_url");
|
||||
tempUser.Signed_up = returnArray[i]->GetString("signed_up");
|
||||
tempUser.Last_Logged_in = returnArray[i]->GetString("last_logged_in");
|
||||
tempUser.status = returnArray[i]->GetString("status");
|
||||
returnUserInfo.Add(tempUser);
|
||||
}
|
||||
|
||||
return returnUserInfo;
|
||||
}
|
||||
|
||||
/* Awards the current user a trophy */
|
||||
bool UUEGameJoltAPI::RewardTrophy(const int32 Trophy_ID)
|
||||
{
|
||||
|
||||
bool ret = true;
|
||||
FString output;
|
||||
FString GameIDString;
|
||||
FString TrophyIDString;
|
||||
GameIDString = FString::FromInt(Game_ID);
|
||||
if (!bIsLoggedIn)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("User is not logged in"));
|
||||
return false;
|
||||
}
|
||||
TrophyIDString = FString::FromInt(Trophy_ID);
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_TROPHIES_ADD;
|
||||
ret = SendRequest(output, "/trophies/add-achieved/?trophy_id=" + TrophyIDString);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Gets information for all trophies */
|
||||
void UUEGameJoltAPI::FetchAllTrophies(const EGameJoltAchievedTrophies AchievedType)
|
||||
{
|
||||
TArray<int32> Trophies;
|
||||
FetchTrophies(AchievedType, Trophies);
|
||||
}
|
||||
|
||||
/* Gets information for the selected trophies */
|
||||
void UUEGameJoltAPI::FetchTrophies(const EGameJoltAchievedTrophies AchievedType, const TArray<int32> Trophy_IDs)
|
||||
{
|
||||
TArray<FTrophyInfo> returnTrophies;
|
||||
bool ret = true;
|
||||
FString output;
|
||||
FString TrophyIDString;
|
||||
FString AchievedString;
|
||||
|
||||
if (!bIsLoggedIn)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("User is not logged in!"));
|
||||
return;
|
||||
}
|
||||
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_TROPHIES_FETCH;
|
||||
if(AchievedType == EGameJoltAchievedTrophies::GJ_ACHIEVEDTROPHY_GAME){
|
||||
|
||||
AchievedString ="false";
|
||||
}
|
||||
else
|
||||
{
|
||||
AchievedString = "true";
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < Trophy_IDs.Num(); i++){
|
||||
TrophyIDString += FString::FromInt(Trophy_IDs[i]);
|
||||
if (i != Trophy_IDs.Num()-1)
|
||||
{
|
||||
TrophyIDString += TEXT(",");
|
||||
}
|
||||
}
|
||||
if (AchievedType == EGameJoltAchievedTrophies::GJ_ACHIEVEDTROPHY_BLANK)//if We Want to get all trophies
|
||||
{
|
||||
ret = SendRequest(output, "/trophies/?" + (Trophy_IDs.Num() > 0 ? "&trophy_id=" : "" + TrophyIDString));
|
||||
}
|
||||
else //if We Want to get what trophies the User achieved have Not Achieved
|
||||
{
|
||||
ret = SendRequest(output, "/trophies/?achieved=" + AchievedString +
|
||||
(Trophy_IDs.Num() > 0 ? "&trophy_id=" : "" + TrophyIDString));
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Could not fetch trophies."));
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Gets the trophy information from the fetched trophies */
|
||||
TArray<FTrophyInfo> UUEGameJoltAPI::GetTrophies()
|
||||
{
|
||||
TArray<FTrophyInfo> returnTrophy;
|
||||
TArray<UUEGameJoltAPI*> returnArray = GetObject("response")->GetObjectArray(GetObject("response"), "trophies");
|
||||
FTrophyInfo tempTrophies;
|
||||
for (int i = 0; i< returnArray.Num(); i++)
|
||||
{
|
||||
|
||||
tempTrophies.Trophy_ID = returnArray[i]->GetInt("id");
|
||||
tempTrophies.Name = returnArray[i]->GetString("title");
|
||||
tempTrophies.Description = returnArray[i]->GetString("description");
|
||||
tempTrophies.Difficulty = returnArray[i]->GetString("difficulty");
|
||||
tempTrophies.image_url = returnArray[i]->GetString("image_url");
|
||||
tempTrophies.achieved = returnArray[i]->GetString("achieved");
|
||||
|
||||
returnTrophy.Add(tempTrophies);
|
||||
}
|
||||
|
||||
return returnTrophy;
|
||||
}
|
||||
|
||||
/* Unachieves a trophy */
|
||||
bool UUEGameJoltAPI::RemoveRewardedTrophy(const int32 Trophy_ID)
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_TROHIES_REMOVE;
|
||||
return SendRequest(output, "/trophies/remove-achieved/?trophy_id=" + FString::FromInt(Trophy_ID));
|
||||
}
|
||||
|
||||
/* Checks if the trophy removel was successful */
|
||||
bool UUEGameJoltAPI::GetTrophyRemovalStatus()
|
||||
{
|
||||
UUEGameJoltAPI* Response = GetObject("response");
|
||||
if(!Response)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Response invalid in GetTrophyRemovalStatus. Was ist called to early?"));
|
||||
return false;
|
||||
}
|
||||
return Response->GetBool("success");
|
||||
}
|
||||
|
||||
/* Returns a list of scores either for a user or globally for a game */
|
||||
bool UUEGameJoltAPI::FetchScoreboard(const int32 ScoreLimit, const int32 Table_id, const int32 BetterThan, const int32 WorseThan)
|
||||
{
|
||||
TArray<FTrophyInfo> returnTrophies;
|
||||
bool ret = true;
|
||||
FString output;
|
||||
FString GameIDString;
|
||||
FString TableIDString;
|
||||
FString ScoreLimitString;
|
||||
|
||||
GameIDString = FString::FromInt(Game_ID);
|
||||
TableIDString = FString::FromInt(Table_id);
|
||||
ScoreLimitString = FString::FromInt(ScoreLimit);
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_SCORES_FETCH;
|
||||
|
||||
ret = SendRequest(output, TEXT("/scores/?game_id=") + GameIDString +
|
||||
(!UserName.IsEmpty() || !bIsLoggedIn ? "&username=" : "") + UserName +
|
||||
(bIsLoggedIn ? "&user_token=" : "") + UserToken +
|
||||
(ScoreLimit > 0 ? "&limit=" + ScoreLimitString : "") +
|
||||
(Table_id > 0 ? "&table_id=" + TableIDString : "") +
|
||||
(BetterThan > 0 ? "&better_than=" + FString::FromInt(BetterThan) : "") +
|
||||
(WorseThan > 0 ? "&worse_than=" + FString::FromInt(WorseThan) : ""));
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Could not fetch scoreboard."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Gets the list of scores fetched with FetchScoreboard */
|
||||
TArray<FScoreInfo> UUEGameJoltAPI::GetScoreboard()
|
||||
{
|
||||
TArray<FScoreInfo> returnScoreInfo;
|
||||
TArray<UUEGameJoltAPI*> returnArray = GetObject("response")->GetObjectArray(GetObject("response"), "scores");
|
||||
FScoreInfo tempScore;
|
||||
for (int i = 0; i < returnArray.Num(); i++)
|
||||
{
|
||||
tempScore.ScoreSort = returnArray[i]->GetInt("sort");
|
||||
tempScore.ScoreString = returnArray[i]->GetString("score");
|
||||
tempScore.ExtraData = returnArray[i]->GetString("extra_data");
|
||||
tempScore.UserName = returnArray[i]->GetString("user");
|
||||
tempScore.UserID = returnArray[i]->GetInt("user_id");
|
||||
tempScore.Guest = returnArray[i]->GetString("guest");
|
||||
tempScore.UnixTimestamp = returnArray[i]->GetString("stored");
|
||||
tempScore.TimeStamp = FDateTime::FromUnixTimestamp(returnArray[i]->GetInt("stored"));
|
||||
returnScoreInfo.Add(tempScore);
|
||||
}
|
||||
return returnScoreInfo;
|
||||
}
|
||||
|
||||
/* Adds an entry to a scoreboard */
|
||||
bool UUEGameJoltAPI::AddScore(const FString UserScore, const int32 UserScore_Sort, const FString GuestUser, const FString extra_data, const int32 table_id)
|
||||
{
|
||||
bool ret = true;
|
||||
FString output;
|
||||
FString GameIDString;
|
||||
FString TableIDString;
|
||||
|
||||
GameIDString = FString::FromInt(Game_ID);
|
||||
TableIDString = FString::FromInt(table_id);
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_SCORES_ADD;
|
||||
ret = SendRequest(output, "/scores/add/?score=" + UserScore +
|
||||
TEXT("&sort=") + FString::FromInt(UserScore_Sort) +
|
||||
(!UserName.IsEmpty() || bIsLoggedIn ? "&username=" : "") + UserName +
|
||||
(bIsLoggedIn ? "&user_token=" : "") + UserToken +
|
||||
(!bIsLoggedIn ? "&guest=" : "") + GuestUser +
|
||||
(!extra_data.IsEmpty() ? "&extra_data=" : "") + extra_data +
|
||||
(table_id > 0 ? "&table_id=" : "") + (table_id > 0 ? TableIDString : ""));
|
||||
if (!ret)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Failed to add user's score"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Fetches all scoreboard tables */
|
||||
bool UUEGameJoltAPI::FetchScoreboardTable()
|
||||
{
|
||||
bool ret = true;
|
||||
FString output;
|
||||
FString GameIDString;
|
||||
|
||||
GameIDString = FString::FromInt(Game_ID);
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_SCORES_TABLE;
|
||||
|
||||
ret = SendRequest(output, "/scores/tables/?");
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Could not fetch scoreboard table"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Creates an array of FScoreTableInfo structs for all scoreboards of the game */
|
||||
TArray<FScoreTableInfo> UUEGameJoltAPI::GetScoreboardTable()
|
||||
{
|
||||
TArray<FScoreTableInfo> returnTableinfo;
|
||||
FScoreTableInfo tempTable;
|
||||
TArray<UUEGameJoltAPI*> returnArray = GetObject("response")->GetObjectArray(GetObject("response"), "tables");
|
||||
for (int i = 0; i < returnArray.Num(); i++)
|
||||
{
|
||||
tempTable.Id = returnArray[i]->GetInt("id");
|
||||
tempTable.Name = returnArray[i]->GetString("name");
|
||||
tempTable.Description = returnArray[i]->GetString("description");
|
||||
tempTable.Primary = returnArray[i]->GetString("primary");
|
||||
returnTableinfo.Add(tempTable);
|
||||
}
|
||||
|
||||
return returnTableinfo;
|
||||
}
|
||||
|
||||
/* Fetches the rank of a highscore */
|
||||
bool UUEGameJoltAPI::FetchRank(const int32 Score, const int32 TableID = 0)
|
||||
{
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_SCORES_RANK;
|
||||
FString output;
|
||||
return SendRequest(output, "/scores/get-rank/?sort=" + FString::FromInt(Score) + ((TableID != 0) ? ("&table_id=" + FString::FromInt(TableID)) : ""));
|
||||
}
|
||||
|
||||
/* Gets the rank of a highscore from the response */
|
||||
int32 UUEGameJoltAPI::GetRank()
|
||||
{
|
||||
UUEGameJoltAPI* response = GetObject("response");
|
||||
if(!response)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Response in GetRank is invalid! Was it called to early? LastActionPerformed is %s"), *UEnum::GetValueAsString<EGameJoltComponentEnum>(LastActionPerformed));
|
||||
return 0;
|
||||
}
|
||||
return GetObject("response")->GetInt("rank");
|
||||
}
|
||||
|
||||
#pragma region Data-Store
|
||||
|
||||
void UUEGameJoltAPI::SetData(EDataStore Type, FString key, FString data)
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_DATASTORE_SET;
|
||||
SendRequest(output, "/data-store/set/?key=" + key + "&data=" + data, Type == EDataStore::User);
|
||||
}
|
||||
|
||||
void UUEGameJoltAPI::FetchData(EDataStore Type, FString key)
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_DATASTORE_FETCH;
|
||||
SendRequest(output, "/data-store/?key=" + key, Type == EDataStore::User);
|
||||
}
|
||||
|
||||
void UUEGameJoltAPI::UpdateData(EDataStore Type, FString key, EDataOperation Operation, FString value)
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_DATASTORE_UPDATE;
|
||||
SendRequest(output, "/data-store/update/?key=" + key + "&value=" + value + "&operation=" + UEnum::GetValueAsString<EDataOperation>(Operation).RightChop(16), Type == EDataStore::User);
|
||||
}
|
||||
|
||||
void UUEGameJoltAPI::RemoveData(EDataStore Type, FString key)
|
||||
{
|
||||
FString output;
|
||||
LastActionPerformed = EGameJoltComponentEnum::GJ_DATASTORE_REMOVE;
|
||||
SendRequest(output, "/data-store/remove/?key=" + key, Type == EDataStore::User);
|
||||
}
|
||||
|
||||
void UUEGameJoltAPI::GetData(bool& Success, FString& DataAsString, int32& DataAsInt)
|
||||
{
|
||||
DataAsString = "";
|
||||
DataAsInt = 0;
|
||||
UUEGameJoltAPI* response = GetObject("response");
|
||||
if(!response)
|
||||
{
|
||||
Success = false;
|
||||
return;
|
||||
}
|
||||
Success = response->GetBool("success");
|
||||
if(!Success)
|
||||
return;
|
||||
|
||||
DataAsString = response->GetString("data");
|
||||
DataAsInt = response->GetInt("data");
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/* Gets nested post data from the object with the specified key */
|
||||
UUEGameJoltAPI* UUEGameJoltAPI::GetObject(const FString& key)
|
||||
{
|
||||
UUEGameJoltAPI* fieldObj = NULL;
|
||||
// Try to get the object field from the data
|
||||
const TSharedPtr<FJsonObject> *outPtr;
|
||||
if (!Data->TryGetObjectField(*key, outPtr)) {
|
||||
// Throw an error and return NULL when the key could not be found
|
||||
UE_LOG(GJAPI, Error, TEXT("Entry '%s' not found in the field data!"), *key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create a new field data object and assign the data
|
||||
fieldObj = UUEGameJoltAPI::Create(contextObject);
|
||||
fieldObj->Data = *outPtr;
|
||||
|
||||
// Return the newly created object
|
||||
return fieldObj;
|
||||
}
|
||||
|
||||
/* Gets a string field */
|
||||
FString UUEGameJoltAPI::GetString(const FString& key) const
|
||||
{
|
||||
FString outString;
|
||||
if (!Data->TryGetStringField(*key, outString))
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Entry '%s' not found in the field data!"), *key);
|
||||
return "";
|
||||
}
|
||||
|
||||
return outString;
|
||||
}
|
||||
|
||||
/* Gets a bool field */
|
||||
bool UUEGameJoltAPI::GetBool(const FString& key)const
|
||||
{
|
||||
bool outBool;
|
||||
if (!Data->TryGetBoolField(*key,outBool))
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Entry '%s' not found in the field data!"), *key);
|
||||
return false;
|
||||
}
|
||||
return outBool;
|
||||
}
|
||||
|
||||
/* Gets an integer field */
|
||||
int32 UUEGameJoltAPI::GetInt(const FString& key) const
|
||||
{
|
||||
int32 outInt;
|
||||
if (!Data->TryGetNumberField(*key, outInt))
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("Entry '%s' not found in the field data!"), *key);
|
||||
return 0;
|
||||
}
|
||||
return outInt;
|
||||
}
|
||||
|
||||
/* Gets a string array of all keys from the post data */
|
||||
TArray<FString> UUEGameJoltAPI::GetObjectKeys(UObject* WorldContextObject)
|
||||
{
|
||||
TArray<FString> stringArray;
|
||||
|
||||
for (auto currJsonValue = Data->Values.CreateConstIterator(); currJsonValue; ++currJsonValue) {
|
||||
stringArray.Add((*currJsonValue).Key);
|
||||
}
|
||||
|
||||
// Return the array, will be empty if unsuccessful
|
||||
return stringArray;
|
||||
}
|
||||
|
||||
/* Gets an array of post data */
|
||||
TArray<UUEGameJoltAPI*> UUEGameJoltAPI::GetObjectArray(UObject* WorldContextObject, const FString& key)
|
||||
{
|
||||
TArray<UUEGameJoltAPI*> objectArray;
|
||||
|
||||
// Try to fetch and assign the array to the array pointer
|
||||
const TArray<TSharedPtr<FJsonValue>> *arrayPtr;
|
||||
if (Data->TryGetArrayField(*key, arrayPtr)) {
|
||||
// Iterate through the input array and create new post data objects for every entry and add them to the objectArray
|
||||
for (int32 i = 0; i < arrayPtr->Num(); i++) {
|
||||
UUEGameJoltAPI* pageData = Create(WorldContextObject);
|
||||
pageData->Data = (*arrayPtr)[i]->AsObject();
|
||||
objectArray.Add(pageData);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Throw an error, since the value with the supplied key could not be found
|
||||
UE_LOG(GJAPI, Error, TEXT("Array entry '%s' not found in the field data!"), *key);
|
||||
}
|
||||
|
||||
// Return the array, will be empty if unsuccessful
|
||||
|
||||
return objectArray;
|
||||
}
|
||||
|
||||
/* Sends a request */
|
||||
bool UUEGameJoltAPI::SendRequest(const FString& output, FString url, bool bAppendUserInfo)
|
||||
{
|
||||
if (Game_PrivateKey == TEXT(""))
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("You must put in your game's private key before you can use any of the API functions."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Game_ID == 0)
|
||||
{
|
||||
UE_LOG(GJAPI, Error, TEXT("You must put in your game's ID before you can use any of the API functions"));
|
||||
return false;
|
||||
}
|
||||
|
||||
FString outStr;
|
||||
TSharedRef<TJsonWriter<TCHAR>> JsonWriter = TJsonWriterFactory<TCHAR>::Create(&outStr);
|
||||
//Start writing the response
|
||||
WriteObject(JsonWriter, "", new FJsonValueObject(Data));
|
||||
JsonWriter->Close();
|
||||
|
||||
//Create URL First
|
||||
url = TEXT("https://") + GJAPI_SERVER + GJAPI_ROOT + GJAPI_VERSION + url + "&game_id=" + FString::FromInt(Game_ID);
|
||||
|
||||
if(bAppendUserInfo)
|
||||
url += "&username=" + UserName + "&user_token=" + UserToken;
|
||||
|
||||
FString signature(FMD5::HashAnsiString(*(url + Game_PrivateKey)));
|
||||
url += TEXT("&signature=") + signature;
|
||||
UE_LOG(GJAPI, Log, TEXT("%s"), *url);
|
||||
|
||||
|
||||
TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
|
||||
HttpRequest->SetVerb("POST");
|
||||
HttpRequest->SetURL(url);
|
||||
HttpRequest->SetHeader("Content-Type", "application/json");
|
||||
HttpRequest->SetContentAsString(output);
|
||||
HttpRequest->OnProcessRequestComplete().BindUObject(this, &UUEGameJoltAPI::OnReady);
|
||||
HttpRequest->ProcessRequest();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/* Writes data */
|
||||
void UUEGameJoltAPI::WriteObject(TSharedRef<TJsonWriter<TCHAR>> writer, FString key, FJsonValue* value) {
|
||||
if (value->Type == EJson::String) {
|
||||
// Write simple string entry, don't a key when it isn't set
|
||||
if (key.Len() > 0) {
|
||||
writer->WriteValue(key, value->AsString());
|
||||
}
|
||||
else {
|
||||
writer->WriteValue(value->AsString());
|
||||
}
|
||||
}
|
||||
else if (value->Type == EJson::Object) {
|
||||
// Write object entry
|
||||
if (key.Len() > 0) {
|
||||
writer->WriteObjectStart(key);
|
||||
}
|
||||
else {
|
||||
writer->WriteObjectStart();
|
||||
}
|
||||
|
||||
// Loop through all the values in the object data
|
||||
TSharedPtr<FJsonObject> objectData = value->AsObject();
|
||||
for (auto objectValue = objectData->Values.CreateIterator(); objectValue; ++objectValue) {
|
||||
// Using recursion to write the key and value to the writer
|
||||
WriteObject(writer, objectValue.Key(), objectValue.Value().Get());
|
||||
}
|
||||
|
||||
writer->WriteObjectEnd();
|
||||
}
|
||||
else if (value->Type == EJson::Array) {
|
||||
// Process array entry
|
||||
writer->WriteArrayStart(key);
|
||||
|
||||
TArray<TSharedPtr<FJsonValue>> objectArray = value->AsArray();
|
||||
for (int32 i = 0; i < objectArray.Num(); i++) {
|
||||
// Use recursion with an empty key to process all the values in the array
|
||||
WriteObject(writer, "", objectArray[i].Get());
|
||||
}
|
||||
|
||||
writer->WriteArrayEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates data from a string */
|
||||
void UUEGameJoltAPI::FromString(const FString& dataString) {
|
||||
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(dataString);
|
||||
|
||||
// Deserialize the JSON data
|
||||
bool isDeserialized = FJsonSerializer::Deserialize(JsonReader, Data);
|
||||
|
||||
if (!isDeserialized || !Data.IsValid()) {
|
||||
UE_LOG(GJAPI, Error, TEXT("JSON data is invalid! Input:\n'%s'"), *dataString);
|
||||
return;
|
||||
}
|
||||
|
||||
// Assign the request content
|
||||
Content = dataString;
|
||||
}
|
||||
|
||||
/* Callback for IHttpRequest::OnProcessRequestComplete() */
|
||||
void UUEGameJoltAPI::OnReady(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) {
|
||||
if (!bWasSuccessful) {
|
||||
UE_LOG(GJAPI, Warning, TEXT("Response was invalid! Please check the URL."));
|
||||
|
||||
// Broadcast the failed event
|
||||
OnFailed.Broadcast();
|
||||
return;
|
||||
}
|
||||
|
||||
// Process the string
|
||||
FromString(Response->GetContentAsString());
|
||||
|
||||
if(!GetObject("response") || (GetObject("response")->GetBool("success") == false && LastActionPerformed != EGameJoltComponentEnum::GJ_SESSION_CHECK))
|
||||
{
|
||||
OnFailed.Broadcast();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(LastActionPerformed)
|
||||
{
|
||||
case EGameJoltComponentEnum::GJ_USER_AUTH:
|
||||
OnUserAuthorized.Broadcast(isUserAuthorize());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_USER_AUTOLOGIN:
|
||||
OnAutoLogin.Broadcast(isUserAuthorize());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_USER_FETCH:
|
||||
OnUserFetched.Broadcast(GetUserInfo()[0]);
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_USERS_FETCH:
|
||||
OnUsersFetched.Broadcast(GetUserInfo());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_USER_FRIENDLIST:
|
||||
OnFriendlistFetched.Broadcast(GetFriendlist());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_SESSION_OPEN:
|
||||
OnSessionOpened.Broadcast(GetSessionStatus());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_SESSION_PING:
|
||||
OnSessionPinged.Broadcast(GetSessionStatus());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_SESSION_CLOSE:
|
||||
OnSessionClosed.Broadcast(GetSessionStatus());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_SESSION_CHECK:
|
||||
OnSessionChecked.Broadcast(GetSessionStatus());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_TROPHIES_FETCH:
|
||||
OnTrophiesFetched.Broadcast(GetTrophies());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_TROHIES_REMOVE:
|
||||
OnTrophyRemoved.Broadcast(GetTrophyRemovalStatus());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_SCORES_ADD:
|
||||
OnScoreAdded.Broadcast(GetObject("response")->GetBool("success"));
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_SCORES_FETCH:
|
||||
OnScoreboardFetched.Broadcast(GetScoreboard());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_SCORES_TABLE:
|
||||
OnScoreboardTableFetched.Broadcast(GetScoreboardTable());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_SCORES_RANK:
|
||||
OnRankFetched.Broadcast(GetRank());
|
||||
break;
|
||||
case EGameJoltComponentEnum::GJ_TIME:
|
||||
OnTimeFetched.Broadcast(ReadServerTime());
|
||||
break;
|
||||
}
|
||||
// Broadcast the result event
|
||||
OnGetResult.Broadcast();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Resets the saved data */
|
||||
void UUEGameJoltAPI::Reset()
|
||||
{
|
||||
if (Data.IsValid())
|
||||
Data.Reset();
|
||||
|
||||
// Created a new JSON Object
|
||||
Data = MakeShareable(new FJsonObject());
|
||||
}
|
Loading…
Reference in a new issue