Contents | Transport layer | Packet format | Application Protocol | Let's write a server |
So maybe you've turned on that checkbox before, and you're wondering what magic it used? Thankfully, source code for that tool is actually shipped along with it (provided you have a legitimate copy) so we can have a look.
...and that's where the trail runs cold. Upon cracking open the source you will just be faced with walls of hardcoded binary data. Let's take a serious look at what we have here instead.
The first important thing to note is that every single reply from easrv is hardcoded. This means their encryption is
also hardcoded, and sure enough the header is hardcoded to 1-53d121c7-a8b3
(in fact, the entire HTTP
header block is a hardcoded string!).
Many of these responses are only rqeuired by specific games. I've not yet compiled a list of which is for what game, but consider it a future expansion coming later :).
services.get
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <services> <item name="cardmng" url="http://localhost:8080/" /> <item name="facility" url="http://localhost:8080/" /> <item name="message" url="http://localhost:8080/" /> <item name="package" url="http://localhost:8080/" /> <item name="pcbevent" url="http://localhost:8080/" /> <item name="pcbtracker" url="http://localhost:8080/" /> <item name="posevent" url="http://localhost:8080/" /> <item name="pkglist" url="http://localhost:8080/" /> <item name="dlstatus" url="http://localhost:8080/" /> <item name="eacoin" url="http://localhost:8080/" /> <item name="lobby" url="http://localhost:8080/" /> <item name="lobby2" url="http://localhost:8080/" /> <item name="local" url="http://localhost:8080/" /> <item name="local2" url="http://localhost:8080/" /> <item name="apsmanager" url="http://localhost:8080/" /> <item name="netlog" url="http://localhost:8080/" /> <item name="ntp" url="ntp://pool.ntp.org/" /> <item name="keepalive" url="http://localhost:8080/keepalive?pa=localhost&ia=localhost&ga=localhost&ma=localhost&t1=2&t2=10" /> </services> </response>
Fairly standard response here. Many more services are listed than actually available, but that's fine. The router
address (ia
), gateway (ga
) and centre (ma
) are all set to
localhost
, ensuring pings succeed.
pcbtracker.alive
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <pcbtracker ecenable="0" eclimit="0" expire="0" limit="0" status="0" /> </response>
Inform the game we have no intention of supporting PASELI. Implementing PASELI involves implementing carding, and is a sizable amount of work. Smart EA exists to start games, not implement all features.
message.get
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <message status="0" /> </response>
Just report that there's nothing to process. Nice and simple.
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <message expire="300" status="0"> <item end="86400" name="sys.mainte" start="0" /> <item end="86400" name="sys.eacoin.mainte" start="0" /> </message> </response>
When maintenance is enabled, we publish two messages. I believe the former is to announce the whole ea network is under maintenance, and the latter PASELI-specific.
facility.get
This packet notably has its encoding bytes as 00 FF
which to the best of my knowledge is not a valid
encoding. I used Shift-JIS here to decode the location name.
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <facility> <location> <id __type="str">US-01</id> <country __type="str">US</country> <region __type="str">.</region> <name __type="str">・ョ・ッ・ョ・・</name> <type __type="u8">0</type> </location> <line> <id __type="str">.</id> <class __type="u8">0</class> </line> <portfw> <globalip __type="ip4">1.0.0.127</globalip> <globalport __type="s16">8888</globalport> <privateport __type="s16">8888</privateport> </portfw> <public> <flag __type="u8">1</flag> <name __type="str">.</name> <latitude __type="str">0</latitude> <longitude __type="str">0</longitude> </public> <share> <eacoin> <notchamount __type="s32">0</notchamount> <notchcount __type="s32">0</notchcount> <supplylimit __type="s32">1000000</supplylimit> </eacoin> <url> <eapass __type="str">http://localhost</eapass> <arcadefan __type="str">http://localhost</arcadefan> <konaminetdx __type="str">http://localhost</konaminetdx> <konamiid __type="str">http://localhost</konamiid> <eagate __type="str">http://localhost</eagate> </url> </share> </facility> </response>
Pretty standard facility.get
response here, full of the usual fake values. Notably not even the share
URLs were lucky enough to get real data.
pcbevent.put
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <pcbevent /> </response>
package.list
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <package expire="1200" status="0" /> </response>
tax.get_phase
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <tax> <phase __type="s32">0</phase> </tax> </response>
eventlog.write
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <eventlog> <gamesession __type="s64">1</gamesession> <logsendflg __type="s32">0</logsendflg> <logerrlevel __type="s32">0</logerrlevel> <evtidnosendflg __type="s32">0</evtidnosendflg> </eventlog> </response>
machine.get_control
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <machine> <command> <arg __type="str">nop</arg> </command> </machine> </response>
info2.common
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <info2> <event_ctrl /> </info2> </response>
pcb2.boot
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <shop2> <sinfo> <nm __type="str">AS</nm> <cl_enbl __type="bool">1</cl_enbl> <cl_h __type="u8">0</cl_h> <cl_m __type="u8">0</cl_m> </sinfo> </shop2> </response>
pcb2.error
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <pcb2 status="0" /> </response>
system.getmaster
Just an error response unless the game is one of...
KGG-*
):<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <system> <result __type="s32">1</result> <strdata1 __type="str">MSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwx</strdata1> <strdata2 __type="str">MSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwx</strdata2> <updatedate __type="u64">1120367223</updatedate> </system> </response>
I36-*
):<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <system> <result __type="s32">1</result> <strdata1 __type="str">MjAxMTA4MTAwMDoxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MQ==</strdata1> <strdata2 __type="str">MSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwx</strdata2> <updatedate __type="u64">1120367223</updatedate> </system> </response>
hdkoperation.get
Only used by Steel Chronicle as far as I can tell
<?xml version="1.0" encoding="SHIFT_JIS"?> <response> <hdkoperation> <nr_entry __type="s32">1</nr_entry> <param __type="str">0,0,0,0,0,0,0,0,0</param> </hdkoperation> </response>
op2_common.get_music_info
This one is really long. It's got its own dedicated page if you really want to see it anyway.
It appears to be specifically for Nostalgia Op.2, however this may be incorrect.