Skip to content

Commit 89598cf

Browse files
committed
User Pics support is now available!
1 parent c07b2a9 commit 89598cf

File tree

3 files changed

+88
-54
lines changed

3 files changed

+88
-54
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Haxe GameJolt Client Changelog
22

3+
## V1.6
4+
- PFP Images for Users are now supported through some OpenFL tools (check `userGraphics` variable for more info)
5+
- The `logged` variable can now be auto-updated every time it's used, so you can check your login state in real-time
6+
- Now parameters (internal ones) are callable by a Map of Strings instead of an Array of String Arrays
7+
38
## V1.5
49
- Code re-arrangement with the help of the `.vscode` files
510
- Instructions in README file were finally fixed out

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# GameJolt Adaptation for FNF and Haxeflixel
1+
# Haxe GameJolt Client
22

33
Heya there! GamerPablito here!
44

5-
Thanks for use this custom client for GameJolt, this has very useful functions for different purposes with a little better performance than the default libraries (such as the flixel file ~~"FlxGameJolt"~~ or the original ~~"gamejoltAPI"~~ library stuff).
5+
Thanks for use this custom client for GameJolt for Haxe, this has very useful functions for different purposes with a little better performance than the default libraries (such as the flixel file ~~"FlxGameJolt"~~ or the original ~~"gamejoltAPI"~~ library stuff).
66

77
This was originally made for some Friday Night Funkin' mods, but it can be used for any game made with Haxeflixel as well.
88

@@ -33,6 +33,9 @@ You must do the same steps from before, then go to the `project.xml` file and ad
3333

3434
```xml
3535
<define name="GAMEJOLT_ALLOWED" if="desktop" unless="ACHIEVEMENTS_ALLOWED" />
36+
37+
<!-- Don't forget to comment the ACHIEVEMENTS_ALLOWED line ofc-->
38+
<!-- define name="ACHIEVEMENTS_ALLOWED" /-->
3639
```
3740

3841
With that on mind, every time you insert a command from this in some part of your game, make sure its limited by the .xml conditional: `#if GAMEJOLT_ALLOWED ... #end` (cuz this client is made for computers only, and without the `ACHIEVEMENTS_ALLOWED` stuff getting in its way).
@@ -55,11 +58,13 @@ class Example extends FlxUIState
5558
}
5659
```
5760

61+
You can find some menu templates that uses this on [here](https://github.com/GamerPablito/FNF-GameJolt-Menus) if you prefer!
62+
5863
## Still have doubts about its use?
5964
If you're still have questions about how to use this client correctly, or if you want some menu templates to begin with for your game (FNF mods or anything else), you're free to talk to me by [Twitter](https://twitter.com/GamerPablito1) or Discord (GamerPablito#3132). I have no kind of special access you need to do this at all!
6065

6166
## Special Thanks
6267
- [EyeDaleHim](https://github.com/EyeDaleHim) : For suggest me about a better command for printing responses
6368
- [MemeHoovy](https://github.com/MemeHovy) : For giving me a hand explaining differences between this integration and TentaRJ's one
64-
- [TentaRJ](https://github.com/TentaRJ) : For being an inspiration for me to create this
69+
- [TentaRJ](https://github.com/TentaRJ) : For being a huge inspiration for me to create this
6570
- [bimagamongMOP](https://bimagamongmopmain.carrd.co/) : For making me realize a gramatical error in the code ("Trophie" to "Trophy")

gamejolt/GJClient.hx

Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package gamejolt;
22

33
import flixel.FlxG;
4+
import flixel.graphics.FlxGraphic;
45
import haxe.Http;
56
import haxe.Json;
67
import haxe.crypto.Md5;
78
import haxe.crypto.Sha1;
9+
import openfl.display.BitmapData;
10+
import openfl.utils.Future;
811

912
using StringTools;
1013

@@ -97,8 +100,6 @@ class GJClient {
97100
--> EVERY COMMAND HERE WILL WORK ONLY IF GUI PARAMETERS EXIST!! <--
98101
----------------------------------------------------------------
99102
*/
100-
static var printPrefix:String = "GJClient:";
101-
102103
/**
103104
* Tells you if some GUI already exists in the game app or not.
104105
* @return Is it available?
@@ -116,12 +117,18 @@ class GJClient {
116117
/**
117118
* Whether you're actually logged in or not.
118119
*/
119-
public static var logged(default, null):Bool = false;
120+
public static var logged(get, never):Bool;
121+
122+
/**
123+
* A list of graphics loaded from other "User-data-fetching" functions.
124+
* They're all clasified by User ID.
125+
*/
126+
public static var userGraphics:Map<Int, FlxGraphic> = [];
120127

121128
/**
122129
* Whether you want the client to show you help messages in the compiling console or not
123130
*/
124-
public static var showMessages:Bool = true;
131+
public static var showMessages:Bool = false;
125132

126133
/**
127134
* If `true`, the functions will use `Md5` encriptation for data processing; if `false`, they'll use `Sha1` encriptation instead.
@@ -166,28 +173,6 @@ class GJClient {
166173
}
167174
}
168175

169-
/**
170-
* Run this command to make sure if the actual GUI inserted about a user really exists in GameJolt.
171-
*
172-
* @param onSuccess Put a function with actions here, they'll be processed if the process finish successfully.
173-
* @param onFail Put a function with actions here, they'll be processed if an error has ocurred during the process.
174-
*/
175-
public static function authUser(?onSuccess:() -> Void, ?onFail:() -> Void) {
176-
var urlData = urlResult(urlConstruct('users', 'auth'), function() {
177-
printMsg('User authenticated successfully!');
178-
if (onSuccess != null)
179-
onSuccess();
180-
}, function() {
181-
printMsg('User authentication failed!');
182-
setUserInfo(null, null);
183-
noDataWarned = false;
184-
if (onFail != null)
185-
onFail();
186-
});
187-
if (urlData != null)
188-
urlData;
189-
}
190-
191176
/**
192177
* This function fetches the information of any user in GameJolt, according to the ID inserted.
193178
*
@@ -201,12 +186,13 @@ class GJClient {
201186
public static function getUserData(?id:Int, ?onSuccess:() -> Void, ?onFail:() -> Void):Null<User> {
202187
var daFormat:Null<User> = null;
203188

204-
var daParam:Null<Array<Array<String>>> = id != null ? [['user_id', Std.string(id)]] : null;
189+
var daParam:Null<Map<String, String>> = id != null ? ['user_id' => Std.string(id)] : null;
205190
var urlData = urlResult(urlConstruct('users', null, daParam, id == null, false), onSuccess);
206191

207192
if (urlData != null) {
208193
if (urlData.users[0] != null) {
209194
daFormat = cast urlData.users[0];
195+
getImage(daFormat.id, daFormat.avatar_url);
210196
printMsg('${urlData.users[0].developer_name}\'s data fetched sucessfully!');
211197
} else {
212198
printMsg('Data fetching of the user (ID: $id) failed!');
@@ -282,7 +268,7 @@ class GJClient {
282268
* (returns `null` if there are no Trophies in the game to fetch or if there's no GUI inserted in the application yet).
283269
*/
284270
public static function getTrophiesList(?achievedOnes:Bool, ?onSuccess:() -> Void, ?onFail:() -> Void):Null<Array<Trophy>> {
285-
var daParam:Null<Array<Array<String>>> = achievedOnes != null ? [['achieved', Std.string(achievedOnes)]] : null;
271+
var daParam:Null<Map<String, String>> = achievedOnes != null ? ['achieved' => Std.string(achievedOnes)] : null;
286272
var urlData = urlResult(urlConstruct('trophies', null, daParam), function() {
287273
printMsg('Trophies list fetched successfully!');
288274
if (onSuccess != null)
@@ -310,7 +296,7 @@ class GJClient {
310296
var daList = getTrophiesList();
311297

312298
if (logged && daList != null) {
313-
var urlData = urlResult(urlConstruct('trophies', 'add-achieved', [['trophy_id', Std.string(id)]]), function() {
299+
var urlData = urlResult(urlConstruct('trophies', 'add-achieved', ['trophy_id' => Std.string(id)]), function() {
314300
for (troph in daList) {
315301
if (troph.id == id) {
316302
if (troph.achieved == false) {
@@ -346,7 +332,7 @@ class GJClient {
346332
var daList = getTrophiesList();
347333

348334
if (logged && daList != null) {
349-
var urlData = urlResult(urlConstruct('trophies', 'remove-achieved', [['trophy_id', Std.string(id)]]), function() {
335+
var urlData = urlResult(urlConstruct('trophies', 'remove-achieved', ['trophy_id' => Std.string(id)]), function() {
350336
for (troph in daList) {
351337
if (troph.id == id) {
352338
if (troph.achieved != false) {
@@ -389,19 +375,19 @@ class GJClient {
389375
*/
390376
public static function getScoresList(fromUser:Bool, ?table_id:Int, ?delimiter:Int, limit:Int = 10, ?onSuccess:() -> Void,
391377
?onFail:() -> Void):Null<Array<Score>> {
392-
var daParams:Array<Array<String>> = [];
378+
var daParams:Map<String, String> = [];
393379

394380
if (table_id != null)
395-
daParams.push(['table_id', Std.string(table_id)]);
381+
daParams.set('table_id', Std.string(table_id));
396382
if (delimiter != null)
397-
daParams.push([delimiter >= 0 ? 'better_than' : 'worse_than', Std.string(Math.abs(delimiter))]);
383+
daParams.set(delimiter >= 0 ? 'better_than' : 'worse_than', Std.string(Math.abs(delimiter)));
398384

399385
if (limit <= 0)
400386
limit = 1;
401387
if (limit > 100)
402388
limit = 100;
403389
if (limit != 10)
404-
daParams.push(['limit', Std.string(limit)]);
390+
daParams.set('limit', Std.string(limit));
405391

406392
var urlData = urlResult(urlConstruct('scores', null, daParams != [] ? daParams : null, fromUser, fromUser), function() {
407393
printMsg('Scores list from the ${table_id == null ? 'Principal Score Table' : 'Table ID:' + Std.string(table_id)} fetched successfully!');
@@ -430,12 +416,12 @@ class GJClient {
430416
*/
431417
public static function submitNewScore(score_content:String, score_value:Int, ?extraInfo:String, ?table_id:Int, ?onSuccess:Score->Void,
432418
?onFail:() -> Void) {
433-
var daParams:Array<Array<String>> = [['score', score_content], ['sort', Std.string(score_value)]];
419+
var daParams:Map<String, String> = ['score' => score_content, 'sort' => Std.string(score_value)];
434420

435421
if (extraInfo != null)
436-
daParams.push(['extra_data', extraInfo]);
422+
daParams.set('extra_data', extraInfo);
437423
if (table_id != null)
438-
daParams.push(['table_id', Std.string(table_id)]);
424+
daParams.set('table_id', Std.string(table_id));
439425

440426
if (logged) {
441427
var urlData = urlResult(urlConstruct('scores', 'add', daParams), function() {
@@ -473,9 +459,9 @@ class GJClient {
473459
var daTempScore = getScoresList(true, table_id, null, 1);
474460

475461
if (logged && daTempScore != null) {
476-
var daParams = [['sort', Std.string(daTempScore[0].sort)]];
462+
var daParams = ['sort' => Std.string(daTempScore[0].sort)];
477463
if (table_id != null)
478-
daParams.push(['table_id', Std.string(table_id)]);
464+
daParams.set('table_id', Std.string(table_id));
479465

480466
var urlData = urlResult(urlConstruct('scores', 'get-rank', daParams, false, false));
481467
var daRank:Int = urlData != null && logged ? urlData.rank : -1;
@@ -506,8 +492,6 @@ class GJClient {
506492
printMsg('Logged Successfully! Welcome back ${getUser()}!');
507493
if (onSuccess != null && !logged && userData != null)
508494
onSuccess(userData);
509-
510-
logged = true;
511495
}, function() {
512496
printMsg('Login process failed!');
513497
if (onFail != null)
@@ -532,7 +516,6 @@ class GJClient {
532516
printMsg('Logged out successfully!');
533517
if (onSuccess != null && logged)
534518
onSuccess();
535-
logged = false;
536519
}, function() {
537520
printMsg('Logout process failed!');
538521
if (onFail != null)
@@ -558,7 +541,6 @@ class GJClient {
558541
printMsg('Ping failed! You\'ve been disconnected!');
559542
if (onFail != null)
560543
onFail();
561-
logged = false;
562544
});
563545
if (urlData != null)
564546
urlData;
@@ -588,28 +570,26 @@ class GJClient {
588570
}
589571

590572
// INTERNAL FUNCTIONS (DON'T ALTER IF YOU DON'T KNOW WHAT YOU'RE DOING!!)
591-
static var curCommand:String = '';
592573
static var noDataWarned:Bool = false;
593574

594575
static function printMsg(message:String)
595576
if (showMessages)
596-
Sys.println('$printPrefix $message');
577+
Sys.println('GJClient: $message');
597578

598-
static function urlConstruct(command:String, ?action:String, ?params:Array<Array<String>>, userAllowed:Bool = true, tokenAllowed:Bool = true):Null<Http> {
579+
static function urlConstruct(command:String, ?action:String, ?params:Map<String, String>, userAllowed:Bool = true, tokenAllowed:Bool = true):Null<Http> {
599580
if (hasLoginInfo() && hasGameInfo()) {
600581
var mainURL:String = "http://api.gamejolt.com/api/game/v1_2/";
601582

602-
curCommand = '$command${action != null ? '/$action' : ''}';
603-
mainURL += curCommand;
583+
mainURL += '$command${action != null ? '/$action' : ''}';
604584
mainURL += '/?game_id=${Std.string(GJKeys.id)}'; // Private Thingie (Fuck you hackers lmao)
605585

606586
if (userAllowed)
607587
mainURL += '&username=${getUser()}';
608588
if (tokenAllowed)
609589
mainURL += '&user_token=${getToken()}';
610590
if (params != null)
611-
for (pars in params)
612-
mainURL += '&${pars[0]}=${pars[1]}';
591+
for (k => v in params)
592+
mainURL += '&$k=$v';
613593

614594
var daEncode:String = mainURL + GJKeys.key; // Private thingie (Fuck you hackers lmao)
615595

@@ -633,7 +613,6 @@ class GJClient {
633613
var result:Null<Dynamic> = null;
634614

635615
if (daUrl != null) {
636-
printMsg('Executing "${curCommand}" ...');
637616
daUrl.onData = function(data:String) {
638617
result = Json.parse(data).response;
639618
if (onSuccess != null)
@@ -650,9 +629,54 @@ class GJClient {
650629
return result;
651630
}
652631

632+
static function authUser(?onSuccess:() -> Void, ?onFail:() -> Void) {
633+
var urlData = urlResult(urlConstruct('users', 'auth'), function() {
634+
printMsg('User authenticated successfully!');
635+
if (onSuccess != null)
636+
onSuccess();
637+
}, function() {
638+
printMsg('User authentication failed!');
639+
setUserInfo(null, null);
640+
noDataWarned = false;
641+
if (onFail != null)
642+
onFail();
643+
});
644+
if (urlData != null)
645+
urlData;
646+
}
647+
648+
static function getImage(id:Int, imageUrl:String) {
649+
printMsg('Loading image from user with ID: $id ...');
650+
651+
var newUrl:String = imageUrl.substring(0, imageUrl.indexOf("/", 23));
652+
newUrl += '/1000';
653+
newUrl += imageUrl.substr(34);
654+
newUrl = newUrl.replace(".jpg", ".png");
655+
656+
var daFuture:Future<BitmapData> = BitmapData.loadFromFile(newUrl);
657+
daFuture.onComplete(function(bmap) {
658+
var newGraphic:FlxGraphic = FlxGraphic.fromBitmapData(bmap);
659+
newGraphic.persist = true;
660+
newGraphic.destroyOnNoUse = false;
661+
userGraphics.set(id, newGraphic);
662+
printMsg('Image loaded successfully from $newUrl');
663+
});
664+
daFuture.onError(e -> printMsg("Image load failed: " + Std.string(e)));
665+
}
666+
653667
static function getUser():Null<String>
654668
return FlxG.save.data.user;
655669

656670
static function getToken():Null<String>
657671
return FlxG.save.data.token;
672+
673+
static function get_logged():Bool {
674+
var result:Bool = false;
675+
var process = urlResult(urlConstruct('sessions', 'check'));
676+
677+
if (process != null)
678+
result = process.success == 'true';
679+
680+
return result;
681+
}
658682
}

0 commit comments

Comments
 (0)