2012-01-21 21:57:41 +01:00
|
|
|
|
/*
|
|
|
|
|
PLAYLOG.C
|
|
|
|
|
This code allows to modify play_rec.dat in order to store the
|
|
|
|
|
game time in Wii's log correctly.
|
|
|
|
|
|
|
|
|
|
by Marc
|
|
|
|
|
Thanks to tueidj for giving me some hints on how to do it :)
|
|
|
|
|
Most of the code was taken from here:
|
|
|
|
|
http://forum.wiibrew.org/read.php?27,22130
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <ogcsys.h>
|
2012-12-08 17:17:35 +01:00
|
|
|
|
#include "gecko/gecko.hpp"
|
2012-01-21 21:57:41 +01:00
|
|
|
|
|
|
|
|
|
#define PLAYRECPATH "/title/00000001/00000002/data/play_rec.dat"
|
|
|
|
|
#define SECONDS_TO_2000 946684800LL
|
|
|
|
|
#define TICKS_PER_SECOND 60750000LL
|
|
|
|
|
|
2012-10-15 00:47:23 +02:00
|
|
|
|
typedef union
|
2012-01-21 21:57:41 +01:00
|
|
|
|
{
|
2012-10-15 00:47:23 +02:00
|
|
|
|
struct
|
2012-01-21 21:57:41 +01:00
|
|
|
|
{
|
2012-10-15 00:47:23 +02:00
|
|
|
|
u32 checksum;
|
|
|
|
|
u16 name[0x28];
|
|
|
|
|
u32 padding1;
|
|
|
|
|
u64 ticks_boot;
|
|
|
|
|
u64 ticks_last;
|
|
|
|
|
char title_id[6];
|
|
|
|
|
u16 padding2[9];
|
2012-01-21 21:57:41 +01:00
|
|
|
|
};
|
2012-10-15 00:47:23 +02:00
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
u32 _checksum;
|
|
|
|
|
u32 data[0x1f];
|
|
|
|
|
};
|
2013-01-01 18:42:46 +01:00
|
|
|
|
} ATTRIBUTE_PACKED playtime_t;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
|
2012-10-15 00:47:23 +02:00
|
|
|
|
playtime_t playrec_buf;
|
2012-01-21 21:57:41 +01:00
|
|
|
|
|
|
|
|
|
// Thanks to Dr. Clipper
|
|
|
|
|
u64 getWiiTime(void)
|
|
|
|
|
{
|
|
|
|
|
time_t uTime = time(NULL);
|
|
|
|
|
return TICKS_PER_SECOND * (uTime - SECONDS_TO_2000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Playlog_Update(const char ID[6], const u8 title[84])
|
|
|
|
|
{
|
2012-10-15 00:47:23 +02:00
|
|
|
|
gprintf("Update Play log\n");
|
2012-01-21 21:57:41 +01:00
|
|
|
|
u32 sum = 0;
|
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
|
|
//Open play_rec.dat
|
|
|
|
|
s32 playrec_fd = IOS_Open(PLAYRECPATH, IPC_OPEN_RW);
|
|
|
|
|
if(playrec_fd == -106)
|
|
|
|
|
{
|
|
|
|
|
gprintf("IOS_Open error ret: %i\n",playrec_fd);
|
|
|
|
|
IOS_Close(playrec_fd);
|
|
|
|
|
|
|
|
|
|
//In case the play_rec.dat wasn<73>t found create one and try again
|
|
|
|
|
if(ISFS_CreateFile(PLAYRECPATH,0,3,3,3) < 0 )
|
|
|
|
|
goto error_2;
|
|
|
|
|
|
|
|
|
|
playrec_fd = IOS_Open(PLAYRECPATH, IPC_OPEN_RW);
|
|
|
|
|
if(playrec_fd < 0)
|
|
|
|
|
goto error_2;
|
|
|
|
|
}
|
|
|
|
|
else if(playrec_fd < 0)
|
|
|
|
|
goto error_2;
|
|
|
|
|
|
|
|
|
|
u64 stime = getWiiTime();
|
|
|
|
|
playrec_buf.ticks_boot = stime;
|
|
|
|
|
playrec_buf.ticks_last = stime;
|
|
|
|
|
|
|
|
|
|
//Update channel name and ID
|
|
|
|
|
memcpy(playrec_buf.name, title, 84);
|
2012-10-15 00:47:23 +02:00
|
|
|
|
strcpy(playrec_buf.title_id, ID);
|
2012-01-21 21:57:41 +01:00
|
|
|
|
|
2012-10-15 00:47:23 +02:00
|
|
|
|
memset(playrec_buf.padding2, 0, 18);
|
2012-01-21 21:57:41 +01:00
|
|
|
|
|
|
|
|
|
//Calculate and update checksum
|
|
|
|
|
for(i=0; i<31; i++)
|
|
|
|
|
sum += playrec_buf.data[i];
|
|
|
|
|
playrec_buf.checksum=sum;
|
|
|
|
|
|
|
|
|
|
//Write play_rec.dat
|
|
|
|
|
if(IOS_Write(playrec_fd, &playrec_buf, sizeof(playrec_buf)) != sizeof(playrec_buf))
|
|
|
|
|
goto error_1;
|
|
|
|
|
|
|
|
|
|
IOS_Close(playrec_fd);
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
error_1:
|
|
|
|
|
gprintf("error_1\n");
|
|
|
|
|
IOS_Close(playrec_fd);
|
|
|
|
|
|
|
|
|
|
error_2:
|
|
|
|
|
gprintf("error_2\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Playlog_Delete(void) //Make Wiiflow not show in playlog
|
|
|
|
|
{
|
|
|
|
|
//Open play_rec.dat
|
|
|
|
|
s32 playrec_fd = IOS_Open(PLAYRECPATH, IPC_OPEN_RW);
|
|
|
|
|
if(playrec_fd < 0)
|
|
|
|
|
goto error_2;
|
|
|
|
|
|
|
|
|
|
//Read play_rec.dat
|
|
|
|
|
if(IOS_Read(playrec_fd, &playrec_buf, sizeof(playrec_buf)) != sizeof(playrec_buf))
|
|
|
|
|
goto error_1;
|
|
|
|
|
|
|
|
|
|
if(IOS_Seek(playrec_fd, 0, 0) < 0)
|
|
|
|
|
goto error_1;
|
|
|
|
|
|
|
|
|
|
// invalidate checksum
|
|
|
|
|
playrec_buf.checksum=0;
|
|
|
|
|
|
|
|
|
|
if(IOS_Write(playrec_fd, &playrec_buf, sizeof(playrec_buf)) != sizeof(playrec_buf))
|
|
|
|
|
goto error_1;
|
|
|
|
|
|
|
|
|
|
IOS_Close(playrec_fd);
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
error_1:
|
|
|
|
|
IOS_Close(playrec_fd);
|
|
|
|
|
|
|
|
|
|
error_2:
|
|
|
|
|
return -1;
|
|
|
|
|
}
|