T2 Linux Server

I noticed a server in the list has a little Penguin, it is noted as a Linux server.

How? I'd gladly host a few different mods, but Penguin power!

Comments

  • There is a native linux port of Tribes 2, but it doesn't support TribesNext accounts (we had considered doing something of a workaround TCP connection between a T2 server and Ruby to do the requisite tasks, but never got around to it). It's been a few years, so I don't recall if the executables in that sub-directory are pre-patched for the LAN check. If not you could apply the fix from here.
  • There is a native linux port of Tribes 2, but it doesn't support TribesNext accounts (we had considered doing something of a workaround TCP connection between a T2 server and Ruby to do the requisite tasks, but never got around to it). It's been a few years, so I don't recall if the executables in that sub-directory are pre-patched for the LAN check. If not you could apply the fix from here.

    I was actually wondering where the Linux port was for a while because it would've been a neat thing to have. I tried running it though and got no luck. LUbuntu 13.10, AMD64 and the "tribes2" executable merely exits right after the "Initializing..." window shows up in LAN. With the patch, the "tribes2.dynamic" executable throws this:
    WARNING: Application is using X11_KeyToUnicode().
    This is not an official SDL function, please report this as a bug.
    ./tribes2.dynamic: symbol lookup error: ./tribes2.dynamic: undefined symbol: SDL_GetGamma

    Edit:
    Noticed the game is actually exiting with:
    Fatal-ISV: (DGL/gFont.cc @ 42) Error, The Arial Font must always be available!
    Error, The Arial Font must always be available!
  • The Loki Linux port is linked against now-very-old Linux userspace libraries (libc, SDL, etc.). To get it working now, you'd probably be best off putting it in an LXC or chroot with a suitably ancient userspace. There are also some subtle incompatibilities in the behavior of some of the script functions related to string processing -- I ran into different behavior with strcmp (which I use liberally in the TribesNext cryptography interface for conversions between bytes and integers), and there are probably others.

    If you want to go down this route for compatibility with TribesNext, you'll mostly be on your own. You'll have to find the engine functions that control visibility of native code to the script interpreter, and hook it up to a Ruby interpreter -- it must be visible as rubyEval to the game script system, take a string to evaluate, and the Ruby interpreter needs to have a global function tsEval, which pushes strings back to the game interpreter for evaluation (which is primarily used in lieu of return). You'll also have to extract the RSA public keys embedded in the TribesNext DLL to verify player keys up to the TribesNext certifying authority key.

    Wrestling with Wine is definitely easier.

    That said, you can run a LAN mode Linux server, and trick the TribesNext master list into adding it. There won't be any of the account or authentication aspects of TribesNext obviously, but the TribesNext client is capable of connecting to LAN mode servers.
  • The Loki Linux port is linked against now-very-old Linux userspace libraries (libc, SDL, etc.). To get it working now, you'd probably be best off putting it in an LXC or chroot with a suitably ancient userspace. There are also some subtle incompatibilities in the behavior of some of the script functions related to string processing -- I ran into different behavior with strcmp (which I use liberally in the TribesNext cryptography interface for conversions between bytes and integers), and there are probably others.

    If you want to go down this route for compatibility with TribesNext, you'll mostly be on your own. You'll have to find the engine functions that control visibility of native code to the script interpreter, and hook it up to a Ruby interpreter -- it must be visible as rubyEval to the game script system, take a string to evaluate, and the Ruby interpreter needs to have a global function tsEval, which pushes strings back to the game interpreter for evaluation (which is primarily used in lieu of return). You'll also have to extract the RSA public keys embedded in the TribesNext DLL to verify player keys up to the TribesNext certifying authority key.

    Wrestling with Wine is definitely easier.

    That said, you can run a LAN mode Linux server, and trick the TribesNext master list into adding it. There won't be any of the account or authentication aspects of TribesNext obviously, but the TribesNext client is capable of connecting to LAN mode servers.

    Oh lawd. I'll tackle this...um, some other day.
  • The Loki Linux port is linked against now-very-old Linux userspace libraries (libc, SDL, etc.). To get it working now, you'd probably be best off putting it in an LXC or chroot with a suitably ancient userspace.

    Got it running with some compatibility libs.
    There are also some subtle incompatibilities in the behavior of some of the script functions related to string processing -- I ran into different behavior with strcmp (which I use liberally in the TribesNext cryptography interface for conversions between bytes and integers), and there are probably others.

    So far I'm only aware of t2csri_gameServerHexAddress() behaving differently than it should be which is causing the game to throw the error "Your client claims to be connecting to x.x.x.x but the server finds this unreasonable."
    If you want to go down this route for compatibility with TribesNext, you'll mostly be on your own. You'll have to find the engine functions that control visibility of native code to the script interpreter, and hook it up to a Ruby interpreter -- it must be visible as rubyEval to the game script system, take a string to evaluate, and the Ruby interpreter needs to have a global function tsEval, which pushes strings back to the game interpreter for evaluation (which is primarily used in lieu of return).

    Got most of this done in an extremely hacky and dumb way. A local ruby server listening on port 2000 acts as my interpreter which imports your crypto.rb and certstore.rb files. I had timing issues (due to the way Tribes 2 operates) with receiving the responses when needed (for tsEval) so I had to opt for changing some of the TS logic. The interpreter server writes its responses to a text file that T2 can access and sticks "" at the end which after its response which T2 constantly reads in a loop looking for said string. Once it is found, the response is extracted, the file cleared and the loop terminates. This keeps the interpreter and game in sync. This pretty much mandated the rubyEval calls to now be in a form like:

    $RubyEnabled = rubyEval("1");
    You'll also have to extract the RSA public keys embedded in the TribesNext DLL to verify player keys up to the TribesNext certifying authority key.

    The only thing I do not have. Furthermore I am no cryptographic expert so I don't really know how the t2csri_verify_auth_signature() Ruby function is implemented either.
    Wrestling with Wine is definitely easier.

    Agreed, I already do have a TribesNext capable install of Tribes 2 running via WINE. However I love T2 and tinkering.
  • You can hack together a compatible strcmp by creating an ASCII table of all values from 0x01 to 0xff and using strstr to find the index of the first character. That should resolve char->int abnormalities across the board. I wrote code to do this when I was messing with the Loki port, but who knows where I put it.

    The problem with emulating rubyEval with a script based piping implementation is that the rubyEval call in TribesNext is assumed to be blocking, and won't return to the caller until after tsEval is executed. You can transform these into a callback type thing, but it would require restructuring the code around every rubyEval call (or anything that indirectly calls it, like sha1sum). Your code will acquire the smell of Javascript callback hell, but it's doable.

    The assorted t2csri_verify_*_signature functions just do a modular exponentiation of the input by the RSA public key. If you're clever, you can actually derive the RSA public key used for account signing with just the public exponent (usually 3 or 65537 in almost all systems, 3 in TribesNext) and two signed accounts. You'll get a value that's k*n for some integer k>=1, with n being the true modulus. A small number above 2 signatures (3-5) run through a greatest common multiple should yield the true n. You could also just replace the rubyintersect.dll file (an executable in disguise) with something that logs its standard-in input, and get the full source to the functions.

    The public keys are also not secret. They were originally hard coded into the DLL to make it intractable for novice programmers to fork off TribesNext and run competing incompatible systems with our patch, but their own keys.

    To make it easy...

    Authentication Signing Public Key:
    type: RSA 4096
    e=3
    n=a2303d7c7d3ff28daa2dfd4f7fddcbb939aa461a3a298f22f4cbc8f87c6e584479861b1a638ea2daf87a18420f65b486cbe70453ce4f5f38a55b30026457eab3ef2716aa409d25cb8b809a9ef06e3bcdc5b37f0d975cca972601d6a6d4be10e8e5994708e878ab846caa58466eea79ccd1b49f9f06e4d6b335ba2b47b6dc81a04167a2c2fa2b9f847c1375cb6fef1a3c7ced04f750a9605fab584d2d2a4bbed6d41d4c2eeb5e223ac3bc6d8ac025f4b25bb1058998f768025baea18272a3bddab58f94a9cb4a14452eaf7a50812e012fc42feb5d986183da134f168b447e4da6e00c351bc679b098b78bfdf3e17efcd65ec3d2098a14426957db5e30fa01292961f3caf3aadb12aff45782dd9f8737953491c90ad4df8b76ef2559b4ef3bae957f964cf4c9ded3d2171c9d190ba5a6a079a3d75f2c583217db626bd4074a2559794b475a9c2384096aa2b4816d2e61c144d1de14164b77428a5329da3a4a8174b6a84d8733495ac6bc7efa981f23b4f401a6216e18771856721c74ff136c1cbe7449de0dff26c04f940d3ce31ef369e3b09932ffe7ffb347554bd2171dc5c79337a6d0dad0f8aa5f45bf054d0d0e5b73eaa83e6fdcaf4cbf2422697aa570823c682d76087b6815b0212c80e3ed550420a45f70533214619efc468548af45b6e73fec0acbae55b08c978c0c3de09c79a50626502c49b541b7bf002508cc5a8095
    

    You should be able to use this hex sequence to find where it is in the t2dll.dll file, and extract the delegation root key used for tags (and the update key which we never used), which I imagine are laid out nearby (look for high entropy 4096 bit regions).
  • You can hack together a compatible strcmp by creating an ASCII table of all values from 0x01 to 0xff and using strstr to find the index of the first character. That should resolve char->int abnormalities across the board. I wrote code to do this when I was messing with the Loki port, but who knows where I put it.

    I recall having a script file that did that ... sometime, somewhere.

    Edit:
    Found it.
    The problem with emulating rubyEval with a script based piping implementation is that the rubyEval call in TribesNext is assumed to be blocking, and won't return to the caller until after tsEval is executed.

    I emulated the blocking with an infinite loop that checks for the response in the text file that the Ruby server is writing to.
    The assorted t2csri_verify_*_signature functions just do a modular exponentiation of the input by the RSA public key. If you're clever, you can actually derive the RSA public key used for account signing with just the public exponent (usually 3 or 65537 in almost all systems, 3 in TribesNext) and two signed accounts. You'll get a value that's k*n for some integer k>=1, with n being the true modulus. A small number above 2 signatures (3-5) run through a greatest common multiple should yield the true n. You could also just replace the rubyintersect.dll file (an executable in disguise) with something that logs its standard-in input, and get the full source to the functions.

    Saw the source laying around in the DLL when spelunking for the key.



    Edit:

    Everything appears to work except for tags and the actual login process. For testing purposes, I fed the code my decrypted client key from my Windows install and the authentication process does operate properly as I've played on the MD2FunHouse server with the Loki port. However I do not know why the login code is still failing with your strCmp patch in place.
  • Make sure that the current working directory of your external Ruby process is the same as the T2 installation, since the login database Ruby scripts assume a path relative to there.
  • Make sure that the current working directory of your external Ruby process is the same as the T2 installation, since the login database Ruby scripts assume a path relative to there.

    Won't be difficult. Though currently I'm fighting a sudden compatibility issue when my LUbuntu system updated recently. The UI's no longer render correctly.

    Edit:

    Found out is was a general issue with the 32bit drivers on my LUbuntu 13.10 system and managed to get it running correctly.
    • Screenshot from 2013-12-17 00:40:22.png
  • You might want to contact P!nkPanther from daen.ch and ask him how he got his native Linux server working.
Sign In or Register to comment.