Skip to content

Commit 5981dda

Browse files
committed
initial release
0 parents  commit 5981dda

File tree

5 files changed

+161
-0
lines changed

5 files changed

+161
-0
lines changed

meson.build

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
project(
2+
'fc3-lsgen',
3+
'c',
4+
license: 'GPL-3.0-or-later',
5+
default_options: ['buildtype=debugoptimized',
6+
'warning_level=2'],
7+
version: '1.0.0'
8+
)
9+
10+
deps = [dependency('libgcrypt', version: '>=1.8'),
11+
dependency('libxml-2.0', version: '>=2.9'),
12+
dependency('glib-2.0', version: '>=2.60')]
13+
14+
PROGVERSION=meson.project_version()
15+
PROGNAME=meson.project_name()
16+
17+
conf_data = configuration_data()
18+
conf_data.set_quoted('VERSION', PROGVERSION)
19+
conf_data.set_quoted('PROGNAME', PROGNAME)
20+
21+
subdir('src')

src/cli.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include <glib.h>
2+
3+
#include "cli.h"
4+
5+
static ProgramOptions options;
6+
static GOptionEntry entries[] = {
7+
{
8+
"gamecfg_file",
9+
'c',
10+
G_OPTION_FLAG_NONE,
11+
G_OPTION_ARG_FILENAME,
12+
&options.gamecfg_path,
13+
"Full path to GameProfile.xml",
14+
"FILE",
15+
},
16+
{
17+
"username",
18+
'u',
19+
G_OPTION_FLAG_NONE,
20+
G_OPTION_ARG_STRING,
21+
&options.username,
22+
"Username or nickname as it appears in Ubisoft Launcher",
23+
"STRING",
24+
},
25+
{
26+
"write",
27+
'w',
28+
G_OPTION_FLAG_REVERSE,
29+
G_OPTION_ARG_NONE,
30+
&options.username,
31+
"Write the generated lockstring to GameProfile.xml",
32+
NULL,
33+
},
34+
{ 0 }
35+
};
36+
37+
ProgramOptions* get_program_options(int *argc, char ***argv) {
38+
GOptionContext *context;
39+
40+
context = g_option_context_new(NULL);
41+
42+
g_option_context_add_main_entries(context, entries, NULL);
43+
g_option_context_parse(context, argc, argv, NULL);
44+
45+
return &options;
46+
}

src/cli.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
typedef struct {
4+
char *gamecfg_path;
5+
char *username;
6+
int write_lockstring;
7+
} ProgramOptions;
8+
9+
ProgramOptions* get_program_options(int *argc, char ***argv);

src/main.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <glib.h>
2+
#include <stdint.h>
3+
#include <gcrypt.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
8+
#include "cli.h"
9+
10+
#define KEY_MAX_LENGHT 57
11+
#define UNLOCKED_DATA_SIZE 32
12+
13+
// From https://github.com/wynick27/GameRE/blob/main/FC3LockStringGenerator/FC3LockStringGenerator/MainWindow.xaml.cs
14+
uint8_t unlocked_data[] = {
15+
0x0f, 0x0f, 0x07, 0x05, 0x07, 0x07, 0x07, 0x07, 0x1f, 0x1f, 0x1b, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b,
16+
0x2f, 0x2f, 0x2d, 0x25, 0x2d, 0x2d, 0x2d, 0x2d, 0x3f, 0x3f, 0x3e, 0x3a, 0x3e, 0x3e, 0x3e, 0x3e
17+
};
18+
19+
20+
uint8_t *encrypt_data(const char *key) {
21+
uint8_t *encrypted_data;
22+
gcry_cipher_hd_t cipher;
23+
size_t key_len;
24+
25+
encrypted_data = malloc(UNLOCKED_DATA_SIZE);
26+
key_len = strlen(key);
27+
28+
gcry_error_t err = gcry_cipher_open(&cipher, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 0);
29+
if (err) {
30+
fprintf(stderr, "Failed to open Blowfish cipher: %s\n", gcry_strerror(err));
31+
exit(1);
32+
}
33+
34+
err = gcry_cipher_setkey(cipher, key, key_len);
35+
if (err) {
36+
fprintf(stderr, "Failed to set Blowfish key: %s\n", gcry_strerror(err));
37+
exit (1);
38+
}
39+
40+
err = gcry_cipher_encrypt(cipher, encrypted_data, UNLOCKED_DATA_SIZE, unlocked_data, UNLOCKED_DATA_SIZE);
41+
if (err) {
42+
fprintf(stderr, "Failed to encrypt data: %s\n", gcry_strerror(err));
43+
exit(1);
44+
}
45+
46+
gcry_cipher_close(cipher);
47+
48+
return encrypted_data;
49+
};
50+
51+
int main(int argc, char **argv) {
52+
ProgramOptions *options;
53+
54+
options = get_program_options(&argc, &argv);
55+
56+
if (strlen(options->username) > KEY_MAX_LENGHT - 1) {
57+
options->username[KEY_MAX_LENGHT - 1] = 0;
58+
}
59+
60+
uint8_t *data = encrypt_data(options->username);
61+
printf("Encrypted data:\n");
62+
for (int i = 0; i < UNLOCKED_DATA_SIZE; i++) {
63+
printf("%02x ", data[i]);
64+
}
65+
66+
printf("\n");
67+
68+
// encode
69+
gchar *base64_str = g_base64_encode(data, UNLOCKED_DATA_SIZE);
70+
printf("Data: %s\n", base64_str);
71+
72+
return 0;
73+
}

src/meson.build

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
configure_file(output: 'config.h',
2+
configuration: conf_data)
3+
4+
src_files = [
5+
'main.c',
6+
'cli.c'
7+
]
8+
9+
executable(PROGNAME,
10+
src_files,
11+
dependencies: deps,
12+
install: true)

0 commit comments

Comments
 (0)