@spinzaf/freefire-api 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +297 -0
- package/config/settings.yaml +26 -0
- package/data/items.json +153075 -0
- package/index.js +3 -0
- package/lib/api.js +229 -0
- package/lib/constants.js +115 -0
- package/lib/crypto.js +15 -0
- package/lib/protobuf.js +51 -0
- package/lib/utils.js +112 -0
- package/package.json +45 -0
- package/proto/MajorLogin.proto +173 -0
- package/proto/PlayerCSStats.proto +43 -0
- package/proto/PlayerPersonalShow.proto +641 -0
- package/proto/PlayerStats.proto +38 -0
- package/proto/SearchAccountByName.proto +13 -0
- package/proto/SetPlayerGalleryShowInfo.proto +70 -0
- package/test/all.js +26 -0
- package/test/items.js +51 -0
- package/test/login.js +16 -0
- package/test/profile.js +40 -0
- package/test/search.js +24 -0
- package/test/stats.js +47 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package SetPlayerGalleryShowInfo;
|
|
4
|
+
|
|
5
|
+
message request {
|
|
6
|
+
uint32 version = 1;
|
|
7
|
+
repeated GalleryShowInfo info_item = 2;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
message request_single {
|
|
11
|
+
uint32 version = 1;
|
|
12
|
+
GalleryShowInfo info_item = 2;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
message GalleryShowInfo {
|
|
16
|
+
GalleryShow_InfoType info_type = 1;
|
|
17
|
+
repeated GalleryShowInfoItem items = 2;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
enum GalleryShow_InfoType {
|
|
21
|
+
InfoType_NONE = 0;
|
|
22
|
+
InfoType_ITEM = 1;
|
|
23
|
+
InfoType_BATTLEPASS = 2;
|
|
24
|
+
InfoType_ACHIEVEMENT = 3;
|
|
25
|
+
InfoType_WEAPONEXP = 4;
|
|
26
|
+
InfoType_SIGNATURE = 5;
|
|
27
|
+
InfoType_BUDDYINFO = 6;
|
|
28
|
+
InfoType_RANKINGSTATS = 7;
|
|
29
|
+
InfoType_LEADERBOARDTITLE = 8;
|
|
30
|
+
InfoType_CLANINFO = 9;
|
|
31
|
+
InfoType_CLANHISOTRYLEADERBOARD = 10;
|
|
32
|
+
InfoType_ACHIEVEMENT_STATS = 11;
|
|
33
|
+
InfoType_BADGE = 12;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
message GalleryShowInfoItem {
|
|
37
|
+
uint32 type = 1;
|
|
38
|
+
uint32 sub_type = 2;
|
|
39
|
+
bool is_extra = 3;
|
|
40
|
+
uint32 position_x = 4;
|
|
41
|
+
uint32 position_y = 5;
|
|
42
|
+
GalleryShowExtraInfo extra_info = 6;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
message GalleryShowExtraInfo {
|
|
46
|
+
string region = 1;
|
|
47
|
+
uint32 level = 2;
|
|
48
|
+
uint32 rank = 3;
|
|
49
|
+
uint32 max_level = 4;
|
|
50
|
+
uint64 friend_id = 5;
|
|
51
|
+
uint32 item_id = 6;
|
|
52
|
+
uint32 item_extra_id = 7;
|
|
53
|
+
uint32 value = 8;
|
|
54
|
+
string key = 9;
|
|
55
|
+
int64 expire_time = 10;
|
|
56
|
+
uint64 leaderboard_id = 11;
|
|
57
|
+
uint32 weapon_id = 12;
|
|
58
|
+
uint32 title_cfg_id = 13;
|
|
59
|
+
uint64 clan_id = 14;
|
|
60
|
+
int64 create_time = 15;
|
|
61
|
+
uint32 series_id = 16;
|
|
62
|
+
uint32 num_id = 17;
|
|
63
|
+
string clan_name = 18;
|
|
64
|
+
uint32 clan_level = 19;
|
|
65
|
+
uint32 clan_frame_id = 20;
|
|
66
|
+
uint32 clan_badge_id = 21;
|
|
67
|
+
bool clan_use_custom_badge = 22;
|
|
68
|
+
string clan_custom_badge = 23;
|
|
69
|
+
uint32 clan_glory_num = 24;
|
|
70
|
+
}
|
package/test/all.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
|
|
3
|
+
const tests = [
|
|
4
|
+
'test/login.js',
|
|
5
|
+
'test/search.js',
|
|
6
|
+
'test/profile.js',
|
|
7
|
+
'test/stats.js',
|
|
8
|
+
'test/items.js'
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
console.log("Running all tests sequentially...\n");
|
|
12
|
+
|
|
13
|
+
for (const testFile of tests) {
|
|
14
|
+
const testName = testFile.split('/')[1];
|
|
15
|
+
console.log(`-------------- ${testName}:`);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
execSync(`node ${testFile}`, { stdio: 'inherit' });
|
|
19
|
+
console.log("\n");
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error(`[!] Test ${testName} failed.`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log("All tests passed successfully!");
|
package/test/items.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const FreeFireAPI = require('../index');
|
|
2
|
+
|
|
3
|
+
async function testItems() {
|
|
4
|
+
const targetUid = process.argv[2] || "12345678";
|
|
5
|
+
console.log(`Starting Items Test for UID: ${targetUid}...`);
|
|
6
|
+
|
|
7
|
+
const api = new FreeFireAPI();
|
|
8
|
+
try {
|
|
9
|
+
console.log(`Getting Player Items...`);
|
|
10
|
+
const items = await api.getPlayerItems(targetUid);
|
|
11
|
+
|
|
12
|
+
if (items) {
|
|
13
|
+
const itemList = items.items || {};
|
|
14
|
+
console.log(`\n--- Summary ---`);
|
|
15
|
+
console.log(`Nickname: ${items.basic_info ? items.basic_info.nickname : "-"}`);
|
|
16
|
+
console.log(`UID: ${items.basic_info ? items.basic_info.accountid : "-"}`);
|
|
17
|
+
console.log(`Outfit Items: ${itemList.outfit ? itemList.outfit.length : 0}`);
|
|
18
|
+
|
|
19
|
+
if (itemList.weapons && itemList.weapons.shown_skins) {
|
|
20
|
+
console.log(`Weapon Items: ${itemList.weapons.shown_skins.length}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (itemList.skills && itemList.skills.equipped) {
|
|
24
|
+
console.log(`Skills Equipped: ${itemList.skills.equipped.length}`);
|
|
25
|
+
console.log(`Skills: ${itemList.skills.equipped.map(s => s.id).join(', ')}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (itemList.pet) {
|
|
29
|
+
console.log(`Pet Name: ${itemList.pet.name || "None"}`);
|
|
30
|
+
if (itemList.pet.id) console.log(`Pet ID: ${itemList.pet.id.name || itemList.pet.id.id}`);
|
|
31
|
+
} else {
|
|
32
|
+
console.log(`Pet: None`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (itemList.outfit && itemList.outfit.length > 0) {
|
|
36
|
+
console.log(`\n--- First 5 Outfits ---`);
|
|
37
|
+
itemList.outfit.slice(0, 5).forEach(i => {
|
|
38
|
+
console.log(`- ${i.name || "Unknown"} (ID: ${i.id})`);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
} else {
|
|
43
|
+
console.log("Items fetch failed or empty.");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
} catch (e) {
|
|
47
|
+
console.error("Items test failed:", e.message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
testItems();
|
package/test/login.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const FreeFireAPI = require('../index');
|
|
2
|
+
|
|
3
|
+
async function testLogin() {
|
|
4
|
+
console.log("Starting Login Test...");
|
|
5
|
+
const api = new FreeFireAPI();
|
|
6
|
+
try {
|
|
7
|
+
const session = await api.login();
|
|
8
|
+
console.log("Login success!");
|
|
9
|
+
console.log(`Token: ${session.token.substring(0, 20)}...`);
|
|
10
|
+
console.log(`OpenID: ${session.openId}`);
|
|
11
|
+
} catch (e) {
|
|
12
|
+
console.error("Login failed:", e.message);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
testLogin();
|
package/test/profile.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const FreeFireAPI = require('../index');
|
|
2
|
+
|
|
3
|
+
async function testProfile() {
|
|
4
|
+
const targetUid = process.argv[2] || "12345678";
|
|
5
|
+
console.log(`Starting Profile Test for UID: ${targetUid}...`);
|
|
6
|
+
|
|
7
|
+
const api = new FreeFireAPI();
|
|
8
|
+
try {
|
|
9
|
+
const profile = await api.getPlayerProfile(targetUid);
|
|
10
|
+
if (profile && profile.basicinfo) {
|
|
11
|
+
console.log(`\n--- Basic Info ---`);
|
|
12
|
+
console.log(`Nickname: ${profile.basicinfo.nickname}`);
|
|
13
|
+
console.log(`Level: ${profile.basicinfo.level}`);
|
|
14
|
+
console.log(`EXP: ${profile.basicinfo.exp}`);
|
|
15
|
+
console.log(`Region: ${profile.basicinfo.region}`);
|
|
16
|
+
console.log(`Likes: ${profile.basicinfo.liked}`);
|
|
17
|
+
console.log(`Created At: ${new Date(profile.basicinfo.createat * 1000).toLocaleString()}`);
|
|
18
|
+
console.log(`Last Login: ${new Date(profile.basicinfo.lastloginat * 1000).toLocaleString()}`);
|
|
19
|
+
|
|
20
|
+
if (profile.claninfo) {
|
|
21
|
+
console.log(`\n--- Clan Info ---`);
|
|
22
|
+
console.log(`Clan Name: ${profile.claninfo.clanname}`);
|
|
23
|
+
console.log(`Clan ID: ${profile.claninfo.clanid}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (profile.petinfo) {
|
|
27
|
+
console.log(`\n--- Pet Info ---`);
|
|
28
|
+
console.log(`Pet Name: ${profile.petinfo.name}`);
|
|
29
|
+
console.log(`Pet Level: ${profile.petinfo.level}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
} else {
|
|
33
|
+
console.log("Profile data incomplete or not found.");
|
|
34
|
+
}
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.error("Profile test failed:", e.message);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
testProfile();
|
package/test/search.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const FreeFireAPI = require('../index');
|
|
2
|
+
|
|
3
|
+
async function testSearch() {
|
|
4
|
+
const searchName = process.argv[2] || "folaa";
|
|
5
|
+
console.log(`Starting Search Test for '${searchName}'...`);
|
|
6
|
+
|
|
7
|
+
const api = new FreeFireAPI();
|
|
8
|
+
try {
|
|
9
|
+
const searchResults = await api.searchAccount(searchName);
|
|
10
|
+
if (searchResults && searchResults.length > 0) {
|
|
11
|
+
console.log(`Found ${searchResults.length} players.`);
|
|
12
|
+
console.log(`Top Result: ${searchResults[0].nickname} (UID: ${searchResults[0].accountid})`);
|
|
13
|
+
searchResults.forEach((res, index) => {
|
|
14
|
+
console.log(`[${index + 1}] ${res.nickname} - UID: ${res.accountid} - LVL: ${res.level}`);
|
|
15
|
+
});
|
|
16
|
+
} else {
|
|
17
|
+
console.log("No players found.");
|
|
18
|
+
}
|
|
19
|
+
} catch (e) {
|
|
20
|
+
console.error("Search failed:", e.message);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
testSearch();
|
package/test/stats.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const FreeFireAPI = require('../index');
|
|
2
|
+
|
|
3
|
+
async function testStats() {
|
|
4
|
+
const targetUid = process.argv[2] || "16207002";
|
|
5
|
+
console.log(`Starting Stats Test for UID: ${targetUid}...`);
|
|
6
|
+
|
|
7
|
+
const api = new FreeFireAPI();
|
|
8
|
+
|
|
9
|
+
const printStats = (title, data) => {
|
|
10
|
+
console.log(`\n--- ${title} ---`);
|
|
11
|
+
if (!data) {
|
|
12
|
+
console.log("No data returned.");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (data.solostats) console.log("Solo:", JSON.stringify(data.solostats, (k, v) => (v && v.value ? v.value : v)));
|
|
16
|
+
if (data.duostats) console.log("Duo:", JSON.stringify(data.duostats, (k, v) => (v && v.value ? v.value : v)));
|
|
17
|
+
if (data.quadstats) console.log("Squad:", JSON.stringify(data.quadstats, (k, v) => (v && v.value ? v.value : v)));
|
|
18
|
+
|
|
19
|
+
if (!data.solostats && !data.duostats && !data.quadstats) {
|
|
20
|
+
console.log("Data:", JSON.stringify(data, null, 2));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
// await api.login();
|
|
26
|
+
console.log("Fetching BR Career...");
|
|
27
|
+
const brCareer = await api.getPlayerStats(targetUid, 'br', 'career');
|
|
28
|
+
printStats("BR Career", brCareer);
|
|
29
|
+
|
|
30
|
+
console.log("Fetching BR Ranked...");
|
|
31
|
+
const brRanked = await api.getPlayerStats(targetUid, 'br', 'ranked');
|
|
32
|
+
printStats("BR Ranked", brRanked);
|
|
33
|
+
|
|
34
|
+
console.log("Fetching CS Career...");
|
|
35
|
+
const csCareer = await api.getPlayerStats(targetUid, 'cs', 'career');
|
|
36
|
+
printStats("CS Career", csCareer);
|
|
37
|
+
|
|
38
|
+
console.log("Fetching CS Ranked...");
|
|
39
|
+
const csRanked = await api.getPlayerStats(targetUid, 'cs', 'ranked');
|
|
40
|
+
printStats("CS Ranked", csRanked);
|
|
41
|
+
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.error("Stats test failed:", e.message);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
testStats();
|