+0 WORD Number of messages +2 n*6 BYTEs Records of 6 bytes each +0 DWORD Address of message in file + 1 +4 WORD Length of message in bytes +x y BYTEs undefined, or the messages
The messages texts are encrypted: each ASCII code is increased by 13dec. A single carriage return (ASCII 0Dh, encrypted 1Ah) is a line break. Empty lines are stored as a line break only (no spaces). Messages do not need to be all of the same length. Messages from Winplan clients may have additional encrypted linefeeds (ASCII 0Ah, encrypted 17h) after the CRs.
Characters with an ASCII code above 242 can't be encrypted in messages. The encryption does not have a "wraparound" (then, 250 + 13 would be 7). Attention: Planets doesn't check this and exits with an "Illegal Function Call" message. Host knows about this problem and replaces the characters with ASCII 13h (encrypted 20h = " ").
Expect messages of at most about one kilobyte each: see under MESSx.DAT for host-side size limits. Of course, real programs don't have arbitrary limits.
Message Type Codes
From Host 3.20 and PHost 2.6c onwards, received messages normally start with a header like this (PHost does this consistently since 3.3c): (-xy000)<<< Headline >>> The headers were introduced to allow sorting the messages in Winplan.
The hyphen identifies this message as a message from the current turn. If there is an "o" instead, it's an older message because the player has missed some turns.
"x" specifies the type of the message. "y" is a race number, and "000" a planet or ship id. The following list shows the existing message types (in the following list, capital letters are variable, the rest is fixed):
(-90XXX) Race-specific mission (Hiss, Dark Sense), XXX is a planet Id. (-a0XXX) Message from 3rd-party add-on, see below. (-afile) TKF File transfer. See below. (-c0XXX) Tim Continuum attacking planet #XXX. XXX is zero for ship attacks and priority points. (-d0XXX) Ship or starbase built at planet #XXX. (-dRXXX) Ship of race R (1..9, a, b) surrendered at base #XXX. (-e0XXX) Emergency call from ship #XXX. (-f0XXX) Ship or planet #XXX has been destroyed or captured. (-g0000) HConfig. (-h0000) External message (see MESS.EXT), usually from the host (SENDMESS); may also read `(-h000)'. (-i0XXX) Ion storm #XXX. (-l0XXX) Minefield #XXX laid. (-m0XXX) Minefield #XXX scanned/swept. (-n0XXX) Intercepted enemy messages: ship #XXX ran on a mine, or planet #XXX being pillaged/RGAed. (-p0XXX) Message from planet #XXX. (-pRXXX) New native life, overtaxed, or bad climate at planet #XXX. R is a native race (0..9) or "c" for colonists. (-r000) Anonymous message. (-rX000) Message from race X (0..9, a, b). (-s0XXX) Message from ship #XXX. #XXX is zero if the ship no longer exists (glory device). (-t0XXX) Terraform status from planet #XXX. (-uXXXX) Message about Ufo #XXXX (this type is not generated by host. Currently, only PCC evaluates it, but other authors are encouraged to use this, too, as it allows a nice and consistent interface for messages associated with an Ufo. PHost uses it for wormhole messages since 4.0e/3.4h). (-w0XXX) Ship #XXX ran on a web mine. (-x0XXX) Explosion on long range sensors (#XXX = sequential number of explosion). (-y0XXX) Meteor on planet #XXX. (-z0XXX) (Bio-)scanner report from planet #XXX.
Some Ids can be longer than 3 characters: (-l) and (-m) on PHost 3.3 with CPNumMinefields>=1000, (-u), possibly (-a) and (-x).
Note that some message types allow both planet and ship Ids in the "000" field (codes `f' and `s' are known to do this). I suggest trying to link the message to a ship first, and if this fails, to the planet.
Generally there are exactly as many (-f) messages as there are VCRs. Knowing this may make it easier assigning these messages to objects.
Add-on Messages (-a0XXX)
For messages starting with "(-a0XXX)", Winplan displays a the file WINPLAN\BMP\VPAUXxxx.BMP in the message reader. Those pictures are not transferred with the RST file; players have to install them in advance. Tim assigns Id numbers.
Range | Used by... ==============|================================================= 010 | Wormhole by Kevin D. Foster and James W. Allan 101..126 | Dan & Dave Add-ons (RacePlus, Starbase+, etc.) 149 | Neutral Zone by Dan Gale 191..192 | HugeRock 1.2 by Ryo Nakamura 202 | Unity by Wolfgang Merkel 401 | Trade 1.20 by Nestor Delfino & Alejandro Biondo 403..405 | 1st Corsarian Satellite Bank by -"- 450 | Space Dragons or Non-Aligned Worlds by Joe Thomas 451 | Non-Aligned Worlds by Joe Thomas 451..454 | Lurkers/Stormfront 500 | Gryphon by Oleg Shvartsman 503..507 | Space Dragons by Joe Thomas 510 | Nemesis by Oleg Shvartsman 528 | JS-Q 601 | Margetios Bazaars 602 | mcpEdge 666..668 | Aliens! (default configuration) 700..717 | RAW! by Dan & Dave 800 | GivePlan by Ryo Nakamura 801 | PName by Ryo Nakamura 802..803 | HugeRock Advanced by Ryo Nakamura 805..816 | Interstellar Pig by Chris Stucchio 870..873 | Portal by Rene Gallati
VPA Data Transmission
VPA data transmissions are normal player-to-player messages where the message body looks like this:
<<< VPA Data Transmission >>> OBJECT: Planet 555 <--- Object & Id DATA: 1234567890 <--- Checksum in ASCII aaaaaaaaaaaaaaaaaaaaaaaaa <--- Data aaaaaaaaaaaaaaaaaaaaaaaaa
Two data characters form one byte. "a" stands for 0, "p" for 15: the value of the byte encoded by two characters is 16*(second char) + (first char). Line breaks are inserted after 40 columns (20 bytes).
The checksum is a 32 bit number, encoded as a signed decimal figure. The lower 16 bits are the size of the data block in bytes, the upper 16 bits are some kind of checksum:
{ let this array contain the characters of the message, i.e. the 'a' to 'p' letters, but not the headers or the linefeeds: }
VAR bytes : ARRAY[0..nchars-1] OF BYTE; sum := 0; i := 0; WHILE i < nchars DO BEGIN X := 256*bytes[i+1] + bytes[i]; sum := 2*sum + X i := i + 2; END
(nchars is the number of characters in the message, i.e. two times the number of bytes to encode) This checksum effectively only depends upon the last 16 bytes of the text to be encoded, that is, the last 32 characters of the message.
Note that the characters are case-insensitive for the decoder, but not for the checksummer. 'A' means the same as 'a', namely the digit 0, but has a different value for checksumming.
The decoded blocks read as follows:
--- Planet ("OBJECT: Planet 123") --- +0 WORD Turn number +2 WORD Turn number +4 WORD Owner of planet +6 81 BYTEs Contents of planet record at offset 4 (Friendly Code), see PDATAx.DAT for description. Unknown values are set to -1. +87 WORD ? ("when") +89 WORD Flags ("EPLN"). Bits 0..7 Owner Bits 8..10 Industry level Bit 14 1 = No starbase Bit 15 1 = Starbase present --- Mine field ("OBJECT: Mine field 29") --- +0 WORD Turn number +2 WORD X +4 WORD Y +6 WORD Owner +8 DWORD Mine units +12 WORD Type 0 Normal 1 Web --- Marker ("OBJECT: Marker") --- +0 BYTE Type 1 Flag "p" 2 Small circle "o" 3 Cross "x" 4 Square "[]" 5 Diamond "<>" 6 Dot "." 7 Circle with arbitrary radius 8 Line 9 Dotted line --- VPA 3.60+: --- 10 Grave "t" 11 Cactus "y" --- VPA 3.63+: --- 12 Black flag "P" 13 White flag "P" 14 Flag "k" 15 Up arrow 16 Up/Right arrow 17 Right arrow 18 Down/Right arrow 19 Down arrow 20 Down/Left arrow 21 Left arrow 22 Up/Left arrow 23 Neutronium marker "Ne" 24 Tritanium marker "Tr" 25 Duranium marker "Du" 26 Molybdenum marker "Mo" 27 Skull +1 BYTE Color (1..15, standard EGA colors, see UFO.HST) +2 WORD X +4 WORD Y +6 BYTE horizontal text justification (0=marker is to the left of the text, 1=center, 2=right) +7 BYTE vertical text justification (0=marker is below the text, 1=center, 2=above) +8 WORD Lines: X extent +10 WORD Lines: Y extent Circles: radius +12 BYTE Length of comment text +13 n BYTEs Comment text
For lines, relative lengths are given. The line goes from (X,Y) to (X+dx,Y+dy).
--- RST Password ("OBJECT: Password 3") [V] --- +0 WORD Turn for which this password is valid +2 BYTE Password length +3 10 BYTEs Password (unused places are filled with garbage) +13 BYTE Sender (number of player who sent this message; the number which is also in the OBJECT: line) +14 BYTE Receiver (who may use this password) +15 WORD Permission flags (currently unused, set to 0)
This record can currently only be used with PCC. The password is not encrypted: the hex encoding can be broken with a calculator, as can the password in the GENx.DAT file, so there would be no point in protecting the password more.
This record enables the specified receiver to open the sender's RST without having to know the password. Such a transmission is only valid for one turn. The transmitted password must match the sender's current password.
Informer Alliance Information
Informer (and other tools, such as EchoView) can transfer information about a player's planets and starbases to allied players. These messages contain in the body:
Allied Planets <-- Signature Passcode : 17 <-- Passcode (optional) 506 69 105 770 809 350 390 <-- Id List 405 908
The Id List contains Ids of all the player's planets, each of which is increased by 500 if the planet has a starbase. The above information thus says, `the sender has a starbase on planet 6, he owns planets 69 and 105, he has a starbase on #270, etc.'.
Note that such messages are easy to fake, so use them with care and do not blindly accept them from anyone. Since the message text does not contain the originator race, you shouldn't forward such a message to anyone: it is of no use for them. The `Passcode' line may be missing. If present, it specifies a passcode both allies must have agreed to (a number between 1 and 9999).
VPHost Binary Data Transfer
VPHost's data transfer messages contain in the body
<< VPHOST Binary Data Transfer >> 80E300000010004586560235F6C6162702645646 5627164796F6E602020202020202020202458656 0264564637020202020202020202020202645646 020202020202020202
When you read this, run either VPUNPACK v2.20 or higher, or VPUTIL v2.50 or higher to process this message.
Each line is up to 40 characters long and encodes 20 bytes. A message contains up to 13 lines with binary data. Two characters encode one byte, using normal hex digits. The only non-standard thing is that the less-significant nibble comes first (!), so the above example starts with the bytes 08h, 3Eh, 00h, 00h.
The decoded data block reads as follows: +0 BYTE Type of block +1 WORD "num" Number of bytes in this message, 1 to 253. +3 WORD Offset into target file. If one block was split into multiple messages, the first message contains the first 253 bytes (offset=0), the second one contains the next 253 bytes (offset=253, because we already have 253), and so on. +5 WORD Index. Zero unless otherwise stated. +7 n BYTEs actual data ("num" bytes)
- Type 6 Block: HConfig (see HCONFIG.HST);
- Type 7 Block: VPConfig (VPHost's configuration file);
- Type 8 Block: Race name. Index is the race number, data contains the 3 race names (30 bytes long, 20 bytes short, 12 bytes adjective = 62 bytes total).
TKF File Transfer
A TKF file transfer message looks like this: (-afile)< FILE: kfvcr5.dat [1/1] > 1'Z+!p!K"!]RJ5!"ga&!fh;H&*=/%!!!!!!7T^oQ [!!!!1\)-&*=/%!!!!!!h"81&H!!!!1\)-&*=/%! !$!!!h"81&H$<rr1\)-&*=/%!!!!!!h"81&H!!!! 1\)-&*=/%!!!!!!h"81&H!!!!1\)-&*=/%!iX/cn ... The header line tells you what file it is, and whether it was split; the body of the message contains the file in radix-85 encoding.
In radix-85 encoding, five characters encode four bytes; therefore, each line encodes 32 bytes. The encoding works as follows: { let code[1] to code[5] be five characters from the message. L is an (unsigned) 32 bit variable. }
L := 0 FOR i:=5 DOWNTO 1 DO L := 85*L + (Ord(code[i]) - 33);
{ now, L contains four bytes } data[1] := L AND 255; data[2] := (L SHR 8) AND 255; data[3] := (L SHR 16) AND 255; data[4] := (L SHR 24) AND 255; Note that this method will always generate files whose size is divisible by four; there is no way to encode "odd" sizes.
These messages are used to transmit "KFVCRx.DAT" files to players.