web: load and save states [Firehawke]

This commit is contained in:
R. Belmont 2013-09-22 20:44:15 +00:00
parent 6b5dea7eba
commit 53470c2c47
6 changed files with 146 additions and 0 deletions

2
.gitattributes vendored
View File

@ -8971,5 +8971,7 @@ web/index.html svneol=native#text/html
web/info.html svneol=native#text/html
web/js/jquery.js svneol=native#text/javascript
web/js/jquery.mobile.js svneol=native#text/javascript
web/loadstate.html svneol=native#text/plain
web/logs.html svneol=native#text/html
web/options.html svneol=native#text/html
web/savestate.html svneol=native#text/plain

View File

@ -76,6 +76,40 @@ static void get_qsvar(const struct mg_request_info *request_info,
mg_get_var(qs, strlen(qs == NULL ? "" : qs), name, dst, dst_len);
}
char* websanitize_statefilename ( char* unsanitized )
{
// It's important that we remove any dangerous characters from any filename
// we receive from a web client. This can be a serious security hole.
// As MAME/MESS policy is lowercase filenames, also lowercase it.
char* sanitized = new char[64];
int insertpoint =0;
char charcompare;
while (*unsanitized != 0)
{
charcompare = *unsanitized;
// ASCII 48-57 are 0-9
// ASCII 97-122 are lowercase A-Z
if ((charcompare >= 48 && charcompare <= 57) || (charcompare >= 97 && charcompare <= 122))
{
sanitized[insertpoint] = charcompare;
insertpoint++;
sanitized[insertpoint] = '\0'; // Make sure we're null-terminated.
}
// ASCII 65-90 are uppercase A-Z. These need to be lowercased.
if (charcompare >= 65 && charcompare <= 90)
{
sanitized[insertpoint] = tolower(charcompare); // Lowercase it
insertpoint++;
sanitized[insertpoint] = '\0'; // Make sure we're null-terminated.
}
unsanitized++;
}
return (sanitized);
}
int web_engine::json_game_handler(struct mg_connection *conn)
{
Json::Value data;
@ -189,6 +223,25 @@ int web_engine::begin_request_handler(struct mg_connection *conn)
else
m_machine->pause();
}
else if(!strcmp(cmd_name,"savestate"))
{
char cmd_val[64];
get_qsvar(request_info, "val", cmd_val, sizeof(cmd_val));
char *filename = websanitize_statefilename(cmd_val);
m_machine->schedule_save(filename);
}
else if(!strcmp(cmd_name,"loadstate"))
{
char cmd_val[64];
get_qsvar(request_info, "val", cmd_val, sizeof(cmd_val));
char *filename = cmd_val;
m_machine->schedule_load(filename);
}
else if(!strcmp(cmd_name,"loadauto"))
{
// This is here to just load the autosave and only the autosave.
m_machine->schedule_load("auto");
}
// Send HTTP reply to the client
mg_printf(conn,

View File

@ -1,4 +1,6 @@
<a href="javascript:executeCommands('togglepause');" data-role="button">Toggle Pause</a>
<a href="javascript:executeCommands('softreset');" data-role="button">Soft reset</a>
<a href="javascript:executeCommands('hardreset');" data-role="button">Hard reset</a>
<a href="javascript:loadContent('savestate');" data-transition="fade" data-role="button">Save State</a>
<a href="javascript:loadContent('loadstate');" data-transition="fade" data-role="button">Load State</a>
<a href="javascript:executeCommands('exit');" data-role="button">Exit</a>

View File

@ -170,3 +170,4 @@
</div>
</body>
</html>

44
web/loadstate.html Normal file
View File

@ -0,0 +1,44 @@
Select position to load from
<!-- Yes, it's a little ugly. I could redo this more cleanly with a little javascript, but not right now. -->
<div data-role="controlgroup" data-type="horizontal">
<a href="javascript:loadContent('commands');" data-role="button">Cancel</a>
<a href="javascript:executeCommands('loadstate&val=auto');" data-role="button">Autosave Slot</a>
<a href="javascript:executeCommands('loadstate&val=0');" data-role="button">0</a>
<a href="javascript:executeCommands('loadstate&val=1');" data-role="button">1</a>
<a href="javascript:executeCommands('loadstate&val=2');" data-role="button">2</a>
<a href="javascript:executeCommands('loadstate&val=3');" data-role="button">3</a>
<a href="javascript:executeCommands('loadstate&val=4');" data-role="button">4</a>
<a href="javascript:executeCommands('loadstate&val=5');" data-role="button">5</a>
<a href="javascript:executeCommands('loadstate&val=6');" data-role="button">6</a>
<a href="javascript:executeCommands('loadstate&val=7');" data-role="button">7</a>
<a href="javascript:executeCommands('loadstate&val=8');" data-role="button">8</a>
<a href="javascript:executeCommands('loadstate&val=9');" data-role="button">9</a>
<a href="javascript:executeCommands('loadstate&val=a');" data-role="button">A</a>
<a href="javascript:executeCommands('loadstate&val=b');" data-role="button">B</a>
<a href="javascript:executeCommands('loadstate&val=c');" data-role="button">C</a>
<a href="javascript:executeCommands('loadstate&val=d');" data-role="button">D</a>
<a href="javascript:executeCommands('loadstate&val=e');" data-role="button">E</a>
<a href="javascript:executeCommands('loadstate&val=f');" data-role="button">F</a>
<a href="javascript:executeCommands('loadstate&val=g');" data-role="button">G</a>
<a href="javascript:executeCommands('loadstate&val=h');" data-role="button">H</a>
<a href="javascript:executeCommands('loadstate&val=i');" data-role="button">I</a>
<a href="javascript:executeCommands('loadstate&val=j');" data-role="button">J</a>
<a href="javascript:executeCommands('loadstate&val=k');" data-role="button">K</a>
<a href="javascript:executeCommands('loadstate&val=l');" data-role="button">L</a>
<a href="javascript:executeCommands('loadstate&val=m');" data-role="button">M</a>
<a href="javascript:executeCommands('loadstate&val=n');" data-role="button">N</a>
<a href="javascript:executeCommands('loadstate&val=o');" data-role="button">O</a>
<a href="javascript:executeCommands('loadstate&val=p');" data-role="button">P</a>
<a href="javascript:executeCommands('loadstate&val=q');" data-role="button">Q</a>
<a href="javascript:executeCommands('loadstate&val=r');" data-role="button">R</a>
<a href="javascript:executeCommands('loadstate&val=s');" data-role="button">S</a>
<a href="javascript:executeCommands('loadstate&val=t');" data-role="button">T</a>
<a href="javascript:executeCommands('loadstate&val=u');" data-role="button">U</a>
<a href="javascript:executeCommands('loadstate&val=v');" data-role="button">V</a>
<a href="javascript:executeCommands('loadstate&val=w');" data-role="button">W</a>
<a href="javascript:executeCommands('loadstate&val=x');" data-role="button">X</a>
<a href="javascript:executeCommands('loadstate&val=y');" data-role="button">Y</a>
<a href="javascript:executeCommands('loadstate&val=z');" data-role="button">Z</a>
</div>

44
web/savestate.html Normal file
View File

@ -0,0 +1,44 @@
Select position to save to
<!-- Yes, it's a little ugly. I could redo this more cleanly with a little javascript, but not right now. -->
<div data-role="controlgroup" data-type="horizontal">
<a href="javascript:loadContent('commands');" data-role="button">Cancel</a>
<a href="javascript:executeCommands('savestate&val=auto');" data-role="button">Autosave Slot</a>
<a href="javascript:executeCommands('savestate&val=0');" data-role="button">0</a>
<a href="javascript:executeCommands('savestate&val=1');" data-role="button">1</a>
<a href="javascript:executeCommands('savestate&val=2');" data-role="button">2</a>
<a href="javascript:executeCommands('savestate&val=3');" data-role="button">3</a>
<a href="javascript:executeCommands('savestate&val=4');" data-role="button">4</a>
<a href="javascript:executeCommands('savestate&val=5');" data-role="button">5</a>
<a href="javascript:executeCommands('savestate&val=6');" data-role="button">6</a>
<a href="javascript:executeCommands('savestate&val=7');" data-role="button">7</a>
<a href="javascript:executeCommands('savestate&val=8');" data-role="button">8</a>
<a href="javascript:executeCommands('savestate&val=9');" data-role="button">9</a>
<a href="javascript:executeCommands('savestate&val=a');" data-role="button">A</a>
<a href="javascript:executeCommands('savestate&val=b');" data-role="button">B</a>
<a href="javascript:executeCommands('savestate&val=c');" data-role="button">C</a>
<a href="javascript:executeCommands('savestate&val=d');" data-role="button">D</a>
<a href="javascript:executeCommands('savestate&val=e');" data-role="button">E</a>
<a href="javascript:executeCommands('savestate&val=f');" data-role="button">F</a>
<a href="javascript:executeCommands('savestate&val=g');" data-role="button">G</a>
<a href="javascript:executeCommands('savestate&val=h');" data-role="button">H</a>
<a href="javascript:executeCommands('savestate&val=i');" data-role="button">I</a>
<a href="javascript:executeCommands('savestate&val=j');" data-role="button">J</a>
<a href="javascript:executeCommands('savestate&val=k');" data-role="button">K</a>
<a href="javascript:executeCommands('savestate&val=l');" data-role="button">L</a>
<a href="javascript:executeCommands('savestate&val=m');" data-role="button">M</a>
<a href="javascript:executeCommands('savestate&val=n');" data-role="button">N</a>
<a href="javascript:executeCommands('savestate&val=o');" data-role="button">O</a>
<a href="javascript:executeCommands('savestate&val=p');" data-role="button">P</a>
<a href="javascript:executeCommands('savestate&val=q');" data-role="button">Q</a>
<a href="javascript:executeCommands('savestate&val=r');" data-role="button">R</a>
<a href="javascript:executeCommands('savestate&val=s');" data-role="button">S</a>
<a href="javascript:executeCommands('savestate&val=t');" data-role="button">T</a>
<a href="javascript:executeCommands('savestate&val=u');" data-role="button">U</a>
<a href="javascript:executeCommands('savestate&val=v');" data-role="button">V</a>
<a href="javascript:executeCommands('savestate&val=w');" data-role="button">W</a>
<a href="javascript:executeCommands('savestate&val=x');" data-role="button">X</a>
<a href="javascript:executeCommands('savestate&val=y');" data-role="button">Y</a>
<a href="javascript:executeCommands('savestate&val=z');" data-role="button">Z</a>
</div>