Firstly: if you were looking for Ben's Mod go there, or my Artemis Cloud Server, AKA "Nebula", otherwise...
A totally unofficial, unsupported copy of some of my Artemis protocol-hacking tools, for decoding the binary TCP protocol used between Artemis (2.x, not Cosmos) clients and servers. My work is based heavily on the artemis-nerds protocol-docs, with many thanks to chrivers, rjwut, AwesomeAidenW, @Starry, @Slate, and many others
nc $server 2010 > fileWhere $server is the name/address of your server (EG 127.0.0.1 if running on the same machine). This captured
file
will
contain most but not quite all of the interesting
server-to-client packets. Unfortunately recent Artemis clients send
a "ClientHeartbeat"
packet every 3 seconds, and the server will disconnect you after
a while if you don't send it.
See mainscreen.pl below for a workaround.
parser.pl --help
for a quick list or
parser.pl --man
for a full manual page. The most useful
one is probably --noobject
to not dump the noisy
(and CPU-hungry) objectBitStream packets (but note you're then not
going to be able to reproduce the complete original binary).$parsers{0x12345678}{0xab} = sub { # Parser for packet type 0x12345678 subtype 0xab: my ($a,$b,$c) = unpack('VVC', shift); print "FunctionName($a,$b,$c);\n"; }; sub FunctionName { # Code to recreate the binary for a (server to client) 0x12345678:0xab packet: s2c pack('VV VVC', 0x12345678,0xab, @_); }It definitely helps to understand Perl's somewhat arcane pack() formats - they are mystic runes, but super-efficient at converting a list of values, of various types, to/from binary formats. The important ones are:
parser.pl
now handles all Artemis 2.000000 to
2.8.x packets cleanly
touch gameover.txt # create a dummy file - see below ./mainscreen.pl 2 main fighter heart gameover.txt | nc $server 2010 | tee capture.bin | ./parser.pl --noobj --nodmx --quit gameover.txt... which will select ship 2, main screen and fighters, and send heartbeats whilst waiting for gameover.txt to be deleted. The netcat will send this to your $server (127.0.0.1 or whatever) and collect all the server2client packets. The tee will save a copy of these to capture.bin. The parser.pl will simultaneously dump the captured data in real-time, except the objectBitStream and DmxMessage packets (which were still saved to capture.bin) and when it sees a GameOver packet, will delete gameover.txt, signalling to mainscreen.pl to exit (which in turn will close the netcat, the tee, and parser.pl itself). The above example is so amazingly useful that I have wrapped it up into...
./logger.sh --heart --loop 1 server.addr.ess "some short description"... which will connect to the server.addr.ess on ship 1 [optional/default], and sit in a loop logging each game to a separate file in a subdirectory "captures" with names like
captures/artemis-YYYY-MM-DD-HHMM.some.short.description.01s.xz
(it xzips them after the game ends). The "01s" fits with a different
naming convention (see portwatch.pl below) but basically means this
is the 01st server stream with that timestamp.
logger.sh
exits the --loop
if/when it gets
a 0-size capture, which is almost always a symptom of netcat failing
to connect to an Artemis server that has gone offline.
portwatch.pl --hex
, parser.pl --hex
and
some of chrivers' tools.
./parser.pl captures/artemis-01s.xz | ./totals.pl > artemis-01s.stats ./parser.pl captures/artemis-02s.xz | ./totals.pl > artemis-02s.stats ./parser.pl captures/artemis-03s.xz | ./totals.pl > artemis-03s.stats ./totals.pl artemis-0[123]s.stats > TOTALS
captures/artemis-YYYY-MM-DD-HHMM-*.xz
, and feed them
through tester.sh, declare "pass" or "fail",
make it easier to unit-test the parser against my big game recording
archive and collect "total stats for all games" etc.
parser.pl [...]
--test
which is good for making sure you have "tested all of
the things" - it will periodically remind you which packets/objects
it has NOT seen.
portwatch.pl 2010 127.0.0.1 2020 \ --in captures/artemis-YYYY-MM-DD-HHMM.#c \ --out captures/artemis-YYYY-MM-DD-HHMM.#sThis accepts connections on the usual port 2010, forwards to a server running on port 2020 (set
networkPort=2020
in
artemis.ini
). The clients have the usual
networkPort=2010
but are connecting via the proxy.
--inject file.in
and/or
--outject file.out
, probably in conjunction with short
code snippets like:
#!/usr/bin/perl -w require 'parser.pl'; Poof(87500,0,25000);... and then
./test.pl >> file.out
to pretend
that packet came from the server, and see how the client reacts
(in this case it renders the fuzzy green cloak/decloak "poof!" kinda
thing at those coords)
strings -el Artemis.exe | ./JamCRC.pl # ... except sometimes the strings have other crap before them so... strings -el Artemis.exe \ | sed -e 'P; s/^.//; P; s/^.//; P; s/^.//' \ | ./JamCRC.pl | grep ^0x902f0b1a # or whatever you packetID is # and in this example you'll find "0x902f0b1a bigMess"
grep
of a particular packet/object you're interested in) and tries to
"help" reverse-engineer the packet formats for you.
It looks at the collection of packets/objects of different lengths, and tries to spot which bytes look like strings, ints,
floats, etc. It definitely can't tell you exactly how to
decode a packet, but it might strongly imply that a particular
packet seems to contain 2 integers and 3 floats, it might even tell
you the approximate min/max of each, then leave you to work
out that these correspond to an ObjectID, something, and X,Y,Z
coords. It's a tool, it's not magic :-p
noseynick.net
right now if
you want to connect your Artemis client to it :-)
parser.pl --hook checkpoint.pm
captures/artemis-blah | perl
will output perl which, instead of using
parser.pl
to output the original binary, will instead
analyse all the objectBitstream
packets, collect info
about all objects "in game", and output them once per heartbeat.
parser.pl --hook starry-lisp.pm captures/artemis-blah | perl
parser.pl --hook spawn.pm captures/artemis-blah | perl
and
instead of recreating the original binary, it gives info when when
objects are spawned or deleted, specifically what they were spawned
or deleted NEAR. This should help answer questions like "who
shot Torp 1234", or "drone 2345 hit who?", or "What was sucked into
blackhole 3456?"
*.snt
files which describe the
ship internals - roughly the floor plans / ship systems that
Engineering sees and repairs. ./TSN-Artemis.ca.pl | nc $server 2010 | ./parser.pl
Artemis.exe
2.x.x), this will
magically allow 32-bit EXEs to use 3 or 4GB of memory instead of
2GB. This seems to reduce the number of "out of memory" crashes,
especially when running Artemis with large mods or missions.
creds.sh
containing your discord bot's credentials - this will NOT be
shared here for obvious security reasons, but it's quite simple, and
the format is described in the top of discord.sh
itself.
There's a parser.pl --discord
and corresponding
logger.sh --discord
option that you may
have spotted if you're really observant. These use
discord.sh
to send GameOverStats to the
#scoring_and_games
channel on
the United Stellar Navy Discord
server.
A 3
B 1
C 5
should be less confusing than
1 3
2 1
3 5
.discord.sh
(above) is good for just sending scores and
snippets of stuff to a channel, but really USN discord needs a more
interactive bot, whose initial purpose will be to watch for games
starting, and kick off a corresponding logger.sh --discord
$server_name_or_ip
to watch your game(s) and report the game
type, level, results stats. The bot became known as
"@Artemis-Puppy", companion to the "@Artemis Kitten" AKA
"@Artemis-Leaderboard" who logs scores for USN players.
controls.ini
into pretty HTML keyboard maps?
See also HaydenBarca's controls.ini re-ordered to be more readable