This commit is contained in:
Farewell_ 2024-02-28 12:31:39 +01:00
parent f2769e094f
commit 5bdad6ebae
5 changed files with 32 additions and 69 deletions

View File

@ -18,14 +18,16 @@ To use it with a game, copy `aimeio.dll` to your `segatools` folder and add the
```ini ```ini
[aimeio] [aimeio]
path=aimeio.dll path=aimeio.dll ;Path to aimeio.dll
scan=0x0D ;Sets the key which will be used to insert a card in game. The default is 'Return' scan=0x0D ;Sets the key which will be used to insert a card in game. The default is 'Return'
;Everything below this line is optional. ;Everything below this line is optional.
;aimePath= ;Manually specify an aime.txt file ;readerOptional=1 ;Make reader optional, so that you can still use the keyboard
;felicaPath= ;Manually specify a felica.txt file ;readerName="" ;Force using a reader by setting it's name (in case multiple readers are detected)
;felicaGen=0 ;Generate a new random card if it's missing from the file ;aimePath="" ;Manually specify an aime.txt file
;felicaPath="" ;Manually specify a felica.txt file
;debug=0 ;Display function calls ;debug=0 ;Display function calls
``` ```
@ -33,8 +35,6 @@ scan=0x0D ;Sets the key which will be used to insert a card in game. The def
If you scan a newer AIC-based Aime, its FeliCa IDm will be provided to the game. The game will not see the correct "access code," but the IDm should be unique to each card so that particular card can still track your plays. If you scan a newer AIC-based Aime, its FeliCa IDm will be provided to the game. The game will not see the correct "access code," but the IDm should be unique to each card so that particular card can still track your plays.
As for Mifare cards, their access code won't be 1:1 with a real reader (i still need to fix this). You can still use them and they will work though !
## Inserting cards ## Inserting cards
By pressing the key you have set in segatools.ini and holding it for a few moments, you will insert a card set in either aime.txt or felica.txt By pressing the key you have set in segatools.ini and holding it for a few moments, you will insert a card set in either aime.txt or felica.txt

View File

@ -132,15 +132,15 @@ end:
} }
#pragma endregion #pragma endregion
#pragma region READER SPECIFIC #pragma region READER
static unsigned int __stdcall reader_poll_thread_proc(void *ctx) static unsigned int __stdcall aime_io_poll_thread_proc(void *ctx)
{ {
if (aime_io_cfg.debug) if (aime_io_cfg.debug)
printf("DEBUG: reader_poll_thread_proc(). \r\n"); printf("DEBUG: aime_io_poll_thread_proc(). \r\n");
while (!READER_POLL_STOP_FLAG) while (!READER_POLL_STOP_FLAG)
{ {
if (card_data.card_type != 0) // Halting polling once a card is found, waiting for the game to read it's value. if (card_data.card_type != 0) // Halting polling once a card is found, waiting for the game to read it's value.
scard_poll(&card_data); scard_poll(&card_data); // We're trying to find a card. If we do, the card's id and type are written to card_data.
} }
return 0; return 0;
@ -155,30 +155,25 @@ uint16_t aime_io_get_api_version(void)
HRESULT aime_io_init(void) HRESULT aime_io_init(void)
{ {
int ret = AllocConsole(); // At init we want to open a console...
// At init we want to open a console...
int ret = AllocConsole();
FILE *fp; FILE *fp;
// someone might already allocated a console - seeing this on fufubot's segatools
if (ret != 0) if (ret != 0) // someone might already allocated a console - seeing this on fufubot's segatools
freopen_s(&fp, "CONOUT$", "w", stdout); // only when we allocate a console, we need to redirect stdout freopen_s(&fp, "CONOUT$", "w", stdout); // only when we allocate a console, we need to redirect stdout
memset(&card_data, 0, sizeof(card_data)); // Init card_data structure memset(&card_data, 0, sizeof(card_data)); // We init the card_data structure
// We then read the segatools config file to get settings. // We then read the segatools config file to get settings.
aime_io_config_read(&aime_io_cfg, L".\\segatools.ini"); aime_io_config_read(&aime_io_cfg, L".\\segatools.ini");
// Find and initialize reader(s) printf("aime_io_init: Initializing SmartCard\n"); // Find and initialize reader(s)
printf("aime_io_init: Initializing SmartCard\n");
if (!scard_init(aime_io_cfg)) if (!scard_init(aime_io_cfg))
{ {
// If we couldn't init reader, error out. printf("aime_io_init: Couldn't init SmartCard\n"); // If we couldn't init reader, error out.
printf("aime_io_init: Couldn't init SmartCard\n");
if (!aime_io_cfg.reader_optional) if (!aime_io_cfg.reader_optional)
return E_FAIL; return E_FAIL;
// If however the readerOptional flag is set to 1 in segatools.ini, continue with keyboard only. printf("aime_io_init: Reader is optional, using keyboard only !\n"); // If however the readerOptional flag is set to 1 in segatools.ini, continue with keyboard only.
printf("aime_io_init: Reader is optional, using keyboard only !\n");
return S_OK; return S_OK;
} }
@ -189,7 +184,7 @@ HRESULT aime_io_init(void)
READER_POLL_THREAD = (HANDLE)_beginthreadex( READER_POLL_THREAD = (HANDLE)_beginthreadex(
NULL, NULL,
0, 0,
reader_poll_thread_proc, aime_io_poll_thread_proc,
NULL, NULL,
0, 0,
NULL); NULL);
@ -205,15 +200,9 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no)
if (unit_no != 0) if (unit_no != 0)
return S_OK; return S_OK;
bool sense;
HRESULT hr;
// Don't do anything more if the scan key is not held // Don't do anything more if the scan key is not held
sense = GetAsyncKeyState(aime_io_cfg.vk_scan) & 0x8000; if (GetAsyncKeyState(aime_io_cfg.vk_scan) & 0x8000)
if (!sense)
{
return S_OK; return S_OK;
}
// Set which card we want to read (we will read the x'th line in the card's file, x being determined by which key is pressed on the keypad). // Set which card we want to read (we will read the x'th line in the card's file, x being determined by which key is pressed on the keypad).
int card = 0; int card = 0;
@ -227,15 +216,11 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no)
} }
} }
HRESULT hr;
printf("aime_io_nfc_poll: Attempting to read card %d from file. \r\n", card); printf("aime_io_nfc_poll: Attempting to read card %d from file. \r\n", card);
// Try AiMe IC // Try AiMe IC
hr = aime_io_read_id_file( hr = aime_io_read_id_file(aime_io_cfg.aime_path, card_data.card_id, 10, card);
aime_io_cfg.aime_path,
card_data.card_id,
10,
card);
if (SUCCEEDED(hr) && hr != S_FALSE) if (SUCCEEDED(hr) && hr != S_FALSE)
{ {
card_data.card_type = Mifare; card_data.card_type = Mifare;
@ -243,17 +228,14 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no)
} }
// Try FeliCa IC // Try FeliCa IC
hr = aime_io_read_id_file( hr = aime_io_read_id_file(aime_io_cfg.felica_path, card_data.card_id, 8, card);
aime_io_cfg.felica_path,
card_data.card_id,
8,
card);
if (SUCCEEDED(hr) && hr != S_FALSE) if (SUCCEEDED(hr) && hr != S_FALSE)
{ {
card_data.card_type = FeliCa; card_data.card_type = FeliCa;
return S_OK; return S_OK;
} }
// We found nothing.
return S_OK; return S_OK;
} }
@ -271,7 +253,7 @@ HRESULT aime_io_nfc_get_aime_id(uint8_t unit_no, uint8_t *luid, size_t luid_size
if (card_data.card_type == Mifare) if (card_data.card_type == Mifare)
{ {
memcpy(luid, card_data.card_id, luid_size); memcpy(luid, card_data.card_id, luid_size);
printf("aime_io_nfc_get_aime_id: Read Aime card from file with uid %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X\r\n", card_data.card_id[0], card_data.card_id[1], card_data.card_id[2], card_data.card_id[3], card_data.card_id[4], card_data.card_id[5], card_data.card_id[6], card_data.card_id[7], card_data.card_id[8], card_data.card_id[9]); printf("aime_io_nfc_get_aime_id: Sending Aime card with luID %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X\r\n", card_data.card_id[0], card_data.card_id[1], card_data.card_id[2], card_data.card_id[3], card_data.card_id[4], card_data.card_id[5], card_data.card_id[6], card_data.card_id[7], card_data.card_id[8], card_data.card_id[9]);
memset(&card_data, 0, sizeof(card_data)); // Reset card_data structure memset(&card_data, 0, sizeof(card_data)); // Reset card_data structure
return S_OK; return S_OK;
@ -285,21 +267,18 @@ HRESULT aime_io_nfc_get_felica_id(uint8_t unit_no, uint64_t *IDm)
if (aime_io_cfg.debug) if (aime_io_cfg.debug)
printf("DEBUG: aime_io_nfc_get_felica_id(unit_no : %d). \r\n", unit_no); printf("DEBUG: aime_io_nfc_get_felica_id(unit_no : %d). \r\n", unit_no);
uint64_t val;
size_t i;
assert(IDm != NULL); assert(IDm != NULL);
if (unit_no != 0) if (unit_no != 0)
return S_FALSE; return S_FALSE;
if (card_data.card_type == FeliCa) if (card_data.card_type == FeliCa)
{ {
val = 0; uint64_t val = 0;
for (i = 0; i < 8; i++) for (size_t i = 0; i < 8; i++)
val = (val << 8) | card_data.card_id[i]; val = (val << 8) | card_data.card_id[i];
*IDm = val; *IDm = val;
printf("aime_io_nfc_get_felica_id: Read FeliCa card from file with uid %02X%02X %02X%02X %02X%02X %02X%02X\r\n", card_data.card_id[0], card_data.card_id[1], card_data.card_id[2], card_data.card_id[3], card_data.card_id[4], card_data.card_id[5], card_data.card_id[6], card_data.card_id[7]); printf("aime_io_nfc_get_felica_id: Sending FeliCa card with IDm %02X%02X %02X%02X %02X%02X %02X%02X\r\n", card_data.card_id[0], card_data.card_id[1], card_data.card_id[2], card_data.card_id[3], card_data.card_id[4], card_data.card_id[5], card_data.card_id[6], card_data.card_id[7]);
memset(&card_data, 0, sizeof(card_data)); // Reset card_data structure memset(&card_data, 0, sizeof(card_data)); // Reset card_data structure
return S_OK; return S_OK;

View File

@ -3,11 +3,8 @@
#include <windows.h> #include <windows.h>
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct aime_io_config struct aime_io_config
{ {

View File

@ -210,9 +210,7 @@ void scard_update(struct card_data *card_data, SCARDCONTEXT _hContext, LPCTSTR _
printf("scard_update: atr Return: len(%zu) = %02x (%08X)\n", sizeof(cByteAtr), (unsigned int)atr, cByteAtr); printf("scard_update: atr Return: len(%zu) = %02x (%08X)\n", sizeof(cByteAtr), (unsigned int)atr, cByteAtr);
// Figure out if we should reverse the UID returned by the card based on the ATR protocol
BYTE cardProtocol = atr[12]; BYTE cardProtocol = atr[12];
if (cardProtocol == SCARD_ATR_PROTOCOL_ISO14443_PART3) if (cardProtocol == SCARD_ATR_PROTOCOL_ISO14443_PART3)
{ {
printf("scard_update: Card protocol: ISO14443_PART3\n"); printf("scard_update: Card protocol: ISO14443_PART3\n");
@ -249,7 +247,6 @@ void scard_update(struct card_data *card_data, SCARDCONTEXT _hContext, LPCTSTR _
else if (cbRecv > 8) else if (cbRecv > 8)
printf("scard_update: taking first 8 bytes of len(uid) = %02X\n", cbRecv); printf("scard_update: taking first 8 bytes of len(uid) = %02X\n", cbRecv);
card_data->card_id_len = 8;
memcpy(card_data->card_id, pbRecv, 8); memcpy(card_data->card_id, pbRecv, 8);
} }

View File

@ -25,30 +25,20 @@
#pragma once #pragma once
#include <winscard.h> #include <winscard.h>
#include <windows.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <src/aimeio.h> #include <src/aimeio.h>
/* card types */ // Card types
enum AIME_CARDTYPE enum AIME_CARDTYPE
{ {
Mifare = 0x01, Mifare = 0x01,
FeliCa = 0x02, FeliCa = 0x02
}; };
// Structure containing card_type, card_id and card_id_len // Structure containing card_type, card_id and card_id_len
struct card_data struct card_data
{ {
/* CARDTYPE */
uint8_t card_type; uint8_t card_type;
/* Card ID */
uint8_t card_id[32]; uint8_t card_id[32];
/* Card ID length */
uint8_t card_id_len;
}; };
bool scard_init(struct aime_io_config config); bool scard_init(struct aime_io_config config);