301 Days (redux)

Another metric leap year of gamedev experiments and such

Jul 22, 2016 - OldDays seitan-spin

Day 68 - Protocol

I wasn’t sure you’d get a Goldie Hahn reference.

In which we learn the binary language of moisture vaporators.

Note: Due to a bit of a situation at work, I’m suddenly very busy again. Rather than lose what little momentum exists, I’ll be doing shorter posts.

Test Every Day

CLIENT_VERSION

Let’s keep striking away at that config file. One we skipped earlier is the CLIENT_VERSION. It appears to be used in only one place, where it is simply communicated to the client along with the APP_VERSION:

DragonsSpine/GameSystems/Network/Protocol.cs GitLab
1668
1669
1670
1671
1672
1673
1674
1675
public static void sendWorldVersion(Character ch)
{
    try
    {
        string message = Protocol.VERSION_SERVER + DragonsSpineMain.APP_VERSION + Protocol.VERSION_SERVER_END;
        message += Protocol.VERSION_CLIENT + DragonsSpineMain.CLIENT_VERSION + Protocol.VERSION_CLIENT_END;
        ch.Write(message);
    }

As might be clear, this is using a custom protocol rather than simple ANSI. So we’ll need to figure out how to connect using this protocol (you can see why I initially skipped this part). sendWorldVersion is called by PrintMainMenu if the character’s protocol is equal to APP_PROTOCOL (also from the config file, and defaulted to “Kesmai” in the original code repo).

So how is the character’s protocol determined? It defaults to “normal” and can be swapped between “normal” and “old-kesmai” at the menu, that’s easy enough to find. But the only place I see it being set to anything else is in Protocol.CheckMenuCommand:

DragonsSpine/GameSystems/Network/Protocol.cs GitLab
818
819
820
821
822
823
824
825
            #region Set Protocol
            if (command == SET_PROTOCOL)
            {
                ch.protocol = DragonsSpineMain.APP_PROTOCOL;
                Menu.PrintMainMenu(ch);
                return true;
            }
            #endregion

Earlier on, we see SET_PROTOCOL = (char)27 + "98" + (char)27, so it seems that this particular escape sequence being sent at any menu will do the trick. I’ll assume that a custom client application just knows to do this itself.

features/config_file.feature GitLab
49
50
51
52
53
54
55
Scenario: CLIENT_VERSION sent at main menu
    Given I use the "minimal" database as-is
    And I set "CLIENT_VERSION" in the config file to "25.6.2.4"
    And the server is started
    When I log on using a standard account
    And I send the protocol command "SET_PROTOCOL"
    Then I receive a CLIENT_VERSION of "25.6.2.4"
features/lib/protocol.rb GitLab
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
PROTOCOL_STRINGS = {
    SET_PROTOCOL: "\e98\e",
    VERSION_CLIENT: "\eV2\e",
    VERSION_CLIENT_END: "\eV3\e"
}

When(/^I send the protocol command "([^"]*)"$/) do |command|
  resp = telnet_command(@connection, PROTOCOL_STRINGS[command.to_sym], /.../)
end

Then(/^I receive a CLIENT_VERSION of "([^"]*)"$/) do |version|
  expectation = PROTOCOL_STRINGS[:VERSION_CLIENT] +
                version +
                PROTOCOL_STRINGS[:VERSION_CLIENT_END]
  expect(@last_resp).to include(expectation)
end
37 scenarios (37 passed)
278 steps (278 passed)
6m58.251s

TODO/Refactor Every Other Day

features/config_file.feature GitLab
172
# TODO: News message included in protocol WorldInformation.

There’s kind of an obvious one, since we just figured out how to trigger the WorldInformation block.

features/config_file.feature GitLab
172
173
174
175
176
177
178
Scenario: NEWS included in WorldInformation
    Given I use the "minimal" database as-is
    And I set "NEWS" in the config file to "This is a test, do not be alarmed."
    And the server is started
    When I log on using a standard account
    And I send the protocol command "SET_PROTOCOL"
    Then I receive a NEWS of "This is a test, do not be alarmed."
features/lib/protocol.rb GitLab
2
3
4
5
6
7
8
PROTOCOL_STRINGS = {
    SET_PROTOCOL: "\e98\e",
    VERSION_CLIENT: "\eV2\e",
    VERSION_CLIENT_END: "\eV3\e",
    NEWS: "\eM1\e",
    NEWS_END: "\eM2\e"
}
features/lib/protocol.rb GitLab
21
22
23
24
25
26
Then(/^I receive a NEWS of "([^"]*)"$/) do |news|
  expectation = PROTOCOL_STRINGS[:NEWS] +
                news +
                PROTOCOL_STRINGS[:NEWS_END]
  expect(@last_resp).to include(expectation)
end
38 scenarios (38 passed)
284 steps (284 passed)
7m8.792s

More fun to be had with the protocol stuff? Of course. Tomorrow.


Useful Stuff


More to come

Day 68 code - tests