Prepping save file support

This commit is contained in:
2025-03-17 15:46:35 -05:00
parent 85615121b2
commit 4be5dadb24
3 changed files with 39 additions and 14 deletions

View File

@ -25,6 +25,7 @@
display: none !important; display: none !important;
} }
</style> </style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js" integrity="sha512-a+SUDuwNzXDvz4XrIcXHuCf089/iJAoN4lmrXJg18XnduKK6YlDHNRalv4yd1N40OKI80tFidF+rqTFKGPoWFQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head> </head>
<body> <body>
@ -85,6 +86,29 @@
clearInterval(initInterval); clearInterval(initInterval);
} }
const md5File = async path => {
const buffer = EJS_emulator.gameManager.FS.readFile(path);
const hash = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hash));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex;
}
const emulatorSave = async () => {
// First, we get the currently saved MD5 hash of all files in the save
// directory
const contents = EJS_emulator.gameManager.FS.readdir('/homeplay/saves').filter(f => !f.startsWith('.'));
const hashes = await Promise.all(contents.map(f => md5File(`/homeplay/saves/${f}`)));
EJS_emulator.gameManager.saveSaveFiles();
const newHashes = await Promise.all(contents.map(f => md5File(`/homeplay/saves/${f}`)));
const changedFiles = contents.filter((f, i) => hashes[i] !== newHashes[i]);
console.log('Changed files', changedFiles);
send({
message: ''
})
}
const send = data => { const send = data => {
window.parent.postMessage(data, '*'); window.parent.postMessage(data, '*');
} }
@ -107,6 +131,10 @@
EJS_emulator.setVolume(data.volume); EJS_emulator.setVolume(data.volume);
break; break;
case 'save':
emulatorSave();
break;
default: default:
console.error('Unknown message', message); console.error('Unknown message', message);
} }
@ -142,11 +170,11 @@
} }
EJS_onSaveState = () => { EJS_onSaveState = () => {
send({ message: 'save' }); send({ message: 'save_state' });
} }
EJS_onLoadState = () => { EJS_onLoadState = () => {
send({ message: 'load' }); send({ message: 'load_state' });
} }
EJS_onGameStart = () => { EJS_onGameStart = () => {

View File

@ -18,15 +18,16 @@ type SendEmulatorMessageVolume = {
type SendEmulatorMessage = ( type SendEmulatorMessage = (
SendEmulatorMessageInit | SendEmulatorMessageInit |
SendEmulatorMessageVolume SendEmulatorMessageVolume |
{ message: 'save' }
); );
type ReceiveEmulatorMessage = ( type ReceiveEmulatorMessage = (
{ message: 'iframe_loaded' } | { message: 'iframe_loaded' } |
{ message: 'start' } | { message: 'start' } |
{ message: 'ready' } | { message: 'ready' } |
{ message: 'save' } | { message: 'save_state' } |
{ message: 'load' } { message: 'load_state' }
); );
export type EmulatorProps = { export type EmulatorProps = {
@ -69,8 +70,8 @@ export const Emulator:React.FC<EmulatorProps> = props => {
case 'start': case 'start':
case 'ready': case 'ready':
case 'load': case 'load_state':
case 'save': case 'save_state':
break; break;
default: default:
console.error('Invalid message received:', msg); console.error('Invalid message received:', msg);

View File

@ -7,12 +7,6 @@ import Error500, { Error500Props } from '../500';
import { extendFragment, includeFragment } from '@/lib/fragment'; import { extendFragment, includeFragment } from '@/lib/fragment';
import { Paginated, paginationQuery } from '@/lib/page'; import { Paginated, paginationQuery } from '@/lib/page';
type Game = {
id: string;
name: string;
system: string;
};
type PageProps = { type PageProps = {
games:Paginated<GameLight>|null; games:Paginated<GameLight>|null;
} | Error500Props; } | Error500Props;
@ -21,7 +15,9 @@ export const getServerSideProps: GetServerSideProps<PageProps> = async () => {
try { try {
const client = await apiClientGet(); const client = await apiClientGet();
const res = await client.query<{ games:Paginated<GameLight> }>({ const res = await client.query<{ games:Paginated<GameLight> }>({
variables: { }, variables: {
after: null,
},
query: gql` query: gql`
${includeFragment(GameLightFragment)} ${includeFragment(GameLightFragment)}
query getGames { query getGames {