mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-07-12 15:04:47 +00:00
Initial commit
This commit is contained in:
parent
2211ed7650
commit
ebb3dc9cdd
10121 changed files with 801 additions and 4 deletions
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
if (!isObject(ServerGroup))
|
||||
{
|
||||
exec("tournament/settings.cs");
|
||||
exec("tournament/login.cs");
|
||||
tn_community_login_initiate();
|
||||
exec("tournament/browser.cs");
|
||||
}
|
||||
143
docs/base/@vl2/tournamentNetClient2.vl2/tournament/browser.cs
Normal file
143
docs/base/@vl2/tournamentNetClient2.vl2/tournament/browser.cs
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
// TribesNext Project
|
||||
// http://www.tribesnext.com/
|
||||
// Copyright 2011
|
||||
|
||||
// Tribes 2 Community System
|
||||
// Robot Browser Client - Prototype
|
||||
|
||||
$TribesNext::Community::Browser::Active = 0;
|
||||
|
||||
function CommunityBrowserInterface::onConnected(%this)
|
||||
{
|
||||
//echo("Browser-Sending: " @ %this.data);
|
||||
%this.primed = 0;
|
||||
%this.send(%this.data);
|
||||
}
|
||||
|
||||
function CommunityBrowserInterface::onDisconnect(%this)
|
||||
{
|
||||
$TribesNext::Community::Browser::Active = 0;
|
||||
tn_community_Browser_executeNextRequest();
|
||||
}
|
||||
|
||||
function CommunityBrowserInterface::onLine(%this, %line)
|
||||
{
|
||||
if (trim(%line) $= "")
|
||||
{
|
||||
%this.primed = 1;
|
||||
return;
|
||||
}
|
||||
if (!%this.primed)
|
||||
return;
|
||||
|
||||
//warn("Browser: " @ %line);
|
||||
%message = getField(%line, 0);
|
||||
switch$ (%message)
|
||||
{
|
||||
// display errors to the user -- some of these should never actually happen
|
||||
case "ERR":
|
||||
if (getField(%line, 1) $= "BROWSER")
|
||||
{
|
||||
%type = getField(%line, 2);
|
||||
switch$ (%type)
|
||||
{
|
||||
// TODO -- implement different message types
|
||||
case "BLAH":
|
||||
%message = "Blah!";
|
||||
default:
|
||||
%message = "Unknown error in browser system: " @ %line;
|
||||
}
|
||||
schedule(500, 0, MessageBoxOK, "ERROR", %message);
|
||||
}
|
||||
case "DCE":
|
||||
%dceCert = collapseEscape(getField(%line, 1));
|
||||
%index = getField(%dceCert, 1);
|
||||
$T2CSRI::ClientDCESupport::DCECert[%index] = %dceCert;
|
||||
case "CEC":
|
||||
$T2CSRI::CommunityCertificate = collapseEscape(getField(%line, 1));
|
||||
// schedule a refresh
|
||||
%expire = getField($T2CSRI::CommunityCertificate, 2);
|
||||
rubyEval("tsEval '$temp=\"' + (" @ %expire @ " - Time.now().to_i).to_s + '\";'");
|
||||
%expire = $temp - 60;
|
||||
if (%expire > 0)
|
||||
{
|
||||
if (isEventPending($TribesNext::Browser::CertRefreshSch))
|
||||
cancel($TribesNext::Browser::CertRefreshSch);
|
||||
$TribesNext::Browser::CertRefreshSch = schedule(1000 * %expire, 0, tn_community_Browser_request_cert);
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule(500, 0, MessageBoxOK, "ERROR", "Received expired certificate from community server. Is your computer's clock set correctly?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function tn_community_browser_initQueue()
|
||||
{
|
||||
if (isObject($BrowserRequestQueue))
|
||||
$BrowserRequestQueue.delete();
|
||||
$BrowserRequestQueue = new MessageVector();
|
||||
}
|
||||
tn_community_browser_initQueue();
|
||||
|
||||
function tn_community_browser_processRequest(%request, %payload)
|
||||
{
|
||||
if (%request !$= "")
|
||||
{
|
||||
%request = "?guid=" @ getField($LoginCertificate, 1) @ "&uuid=" @ $TribesNext::Community::UUID @ "&" @ %request;
|
||||
}
|
||||
if (%payload $= "")
|
||||
{
|
||||
%data = "GET " @ $TribesNext::Community::BaseURL @ $TribesNext::Community::BrowserScript @ %request;
|
||||
%data = %data @ " HTTP/1.1\r\nHost: " @ $TribesNext::Community::Host @ "\r\nUser-Agent: Tribes 2\r\nConnection: close\r\n\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
%data = "POST " @ $TribesNext::Community::BaseURL @ $TribesNext::Community::BrowserScript @ " HTTP/1.1\r\n";
|
||||
%data = %data @ "Host: " @ $TribesNext::Community::Host @ "\r\nUser-Agent: Tribes 2\r\nConnection: close\r\n";
|
||||
%data = %data @ %payload;
|
||||
}
|
||||
|
||||
$BrowserRequestQueue.pushBackLine(%data);
|
||||
|
||||
if (!$TribesNext::Community::Browser::Active)
|
||||
tn_community_browser_executeNextRequest();
|
||||
}
|
||||
|
||||
function tn_community_browser_executeNextRequest()
|
||||
{
|
||||
if ($BrowserRequestQueue.getNumLines() <= 0)
|
||||
return;
|
||||
|
||||
%data = $BrowserRequestQueue.getLineText(0);
|
||||
$BrowserRequestQueue.popFrontLine();
|
||||
|
||||
$TribesNext::Community::Browser::Active = 1;
|
||||
|
||||
if (isObject(CommunityBrowserInterface))
|
||||
{
|
||||
CommunityBrowserInterface.disconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
new TCPObject(CommunityBrowserInterface);
|
||||
}
|
||||
CommunityBrowserInterface.data = %data;
|
||||
CommunityBrowserInterface.connect($TribesNext::Community::Host @ ":" @ $TribesNext::Community::Port);
|
||||
}
|
||||
|
||||
// implementation of API requests
|
||||
|
||||
function tn_community_Browser_request_cert()
|
||||
{
|
||||
if ($TribesNext::Community::UUID $= "")
|
||||
{
|
||||
schedule(3000, 0, tn_community_Browser_request_cert);
|
||||
return;
|
||||
}
|
||||
//error("Browser: Downloading enhanced certificate from community server.");
|
||||
tn_community_Browser_processRequest("method=cert");
|
||||
}
|
||||
|
||||
schedule(3000, 0, tn_community_Browser_request_cert);
|
||||
185
docs/base/@vl2/tournamentNetClient2.vl2/tournament/login.cs
Normal file
185
docs/base/@vl2/tournamentNetClient2.vl2/tournament/login.cs
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
// TribesNext Project
|
||||
// http://www.tribesnext.com/
|
||||
// Copyright 2011
|
||||
|
||||
// Tribes 2 Community System
|
||||
// Robot Session Client
|
||||
|
||||
// Since the game itself does not store the users' passwords for any longer than is required
|
||||
// to decrypt their RSA private keys, the "robot" client must negotiate sessions through an
|
||||
// RSA challenge/response.
|
||||
|
||||
// The robot client issues a challenge request by sending the user's GUID and a random nonce.
|
||||
// The DCE issues a challenge that is encrypted with the user's public key. The challenge is
|
||||
// valid for a server configured lifetime, during which any challenge request by the same GUID
|
||||
// would return the same challenge. The client sends the decrypted challenge back to the DCE, and
|
||||
// if it is a match, a session is initiated, and a session UUID is returned to the robot client,
|
||||
// which it uses to verify its identity for all authenticated requests. The challenge lifetime is
|
||||
// sufficiently generous to allow an RSA decryption and heavy network latency.
|
||||
|
||||
// The client will refresh periodically (every 10 minutes by default) to keep the session alive.
|
||||
|
||||
function CommunitySessionInterface::onLine(%this, %line)
|
||||
{
|
||||
//warn("SInterf: " @ %line);
|
||||
if (trim(%line) $= "")
|
||||
{
|
||||
%this.primed = 1;
|
||||
return;
|
||||
}
|
||||
if (%this.primed)
|
||||
{
|
||||
echo(%line);
|
||||
if (getSubStr(%line, 0, 11) $= "CHALLENGE: ")
|
||||
{
|
||||
$TribesNext::Community::SessionErrors = 0;
|
||||
$TribesNext::Community::Challenge = getSubStr(%line, 11, strlen(%line));
|
||||
//error("Challenge set: " @ $TribesNext::Community::Challenge);
|
||||
|
||||
cancel($TribesNext::Community::SessionSchedule);
|
||||
$TribesNext::Community::SessionSchedule = schedule(200, 0, tn_community_login_initiate);
|
||||
}
|
||||
else if (getSubStr(%line, 0, 6) $= "UUID: ")
|
||||
{
|
||||
$TribesNext::Community::SessionErrors = 0;
|
||||
$TribesNext::Community::UUID = getSubStr(%line, 6, strlen(%line));
|
||||
$TribesNext::Community::Challenge = "";
|
||||
//error("UUID set: " @ $TribesNext::Community::UUID);
|
||||
|
||||
cancel($TribesNext::Community::SessionSchedule);
|
||||
$TribesNext::Community::SessionSchedule = schedule($TribesNext::Community::SessionRefresh * 1000, 0, tn_community_login_initiate);
|
||||
}
|
||||
else if (getSubStr(%line, 0, 5) $= "ERR: ")
|
||||
{
|
||||
error("Session negotiation error: " @ getSubStr(%line, 5, strlen(%line)));
|
||||
$TribesNext::Community::UUID = "";
|
||||
$TribesNext::Community::Challenge = "";
|
||||
|
||||
// add schedule with backoff, up to about 15 minutes
|
||||
$TribesNext::Community::SessionErrors++;
|
||||
if ($TribesNext::Community::SessionErrors > 66)
|
||||
$TribesNext::Community::SessionErrors = 66;
|
||||
$TribesNext::Community::SessionSchedule = schedule(200 * ($TribesNext::Community::SessionErrors * $TribesNext::Community::SessionErrors), 0, tn_community_login_initiate);
|
||||
}
|
||||
else if (getSubStr(%line, 0, 9) $= "REFRESHED")
|
||||
{
|
||||
$TribesNext::Community::SessionErrors = 0;
|
||||
//error("Session refreshed. Scheduling next ping.");
|
||||
|
||||
cancel($TribesNext::Community::SessionSchedule);
|
||||
$TribesNext::Community::SessionSchedule = schedule($TribesNext::Community::SessionRefresh * 1000, 0, tn_community_login_initiate);
|
||||
}
|
||||
else if (getSubStr(%line, 0, 7) $= "TIMEOUT")
|
||||
{
|
||||
$TribesNext::Community::SessionErrors = 0;
|
||||
//error("Session timed out. Refreshing.");
|
||||
$TribesNext::Community::UUID = "";
|
||||
$TribesNext::Community::Challenge = "";
|
||||
|
||||
cancel($TribesNext::Community::SessionSchedule);
|
||||
$TribesNext::Community::SessionSchedule = schedule(200, 0, tn_community_login_initiate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function CommunitySessionInterface::onConnected(%this)
|
||||
{
|
||||
//echo("Sending: " @ %this.data);
|
||||
%this.primed = 0;
|
||||
%this.send(%this.data);
|
||||
}
|
||||
|
||||
// initiates the session negotiation process
|
||||
function tn_community_login_initiate()
|
||||
{
|
||||
if (isEventPending($TribesNext::Community::SessionSchedule))
|
||||
{
|
||||
cancel($TribesNext::Community::SessionSchedule);
|
||||
}
|
||||
%payload = "GET " @ $TribesNext::Community::BaseURL @ $TribesNext::Community::LoginScript @ "?guid=" @ getField($LoginCertificate, 1) @ "&";
|
||||
// is there an existing session?
|
||||
if ($TribesNext::Community::UUID !$= "")
|
||||
{
|
||||
// try to refresh it
|
||||
%payload = %payload @ "uuid=" @ $TribesNext::Community::UUID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no session -- either expired, or never had one
|
||||
|
||||
// is a challenge present
|
||||
if ($TribesNext::Community::Challenge $= "")
|
||||
{
|
||||
// no challenge present... ask for one:
|
||||
// create a random nonce half of the length of the active RSA key modulus
|
||||
%length = strlen(getField($LoginCertificate, 3)) / 2;
|
||||
%nonce = "1"; // start with a one to prevent truncation issues
|
||||
for (%i = 1; %i < %length; %i++)
|
||||
{
|
||||
%nibble = getRandom(0, 15);
|
||||
if (%nibble == 10)
|
||||
%nibble = "a";
|
||||
else if (%nibble == 11)
|
||||
%nibble = "b";
|
||||
else if (%nibble == 12)
|
||||
%nibble = "c";
|
||||
else if (%nibble == 13)
|
||||
%nibble = "d";
|
||||
else if (%nibble == 14)
|
||||
%nibble = "e";
|
||||
else if (%nibble >= 15)
|
||||
%nibble = "f";
|
||||
%nonce = %nonce @ %nibble;
|
||||
}
|
||||
$TribesNext::Community::Nonce = %nonce;
|
||||
// transmit the request to the community server
|
||||
%payload = %payload @ "nonce=" @ %nonce;
|
||||
}
|
||||
else
|
||||
{
|
||||
%challenge = strlwr($TribesNext::Community::Challenge);
|
||||
for (%i = 0; %i < strlen(%challenge); %i++)
|
||||
{
|
||||
%char = strcmp(getSubStr(%challenge, %i, 1), "");
|
||||
if ((%char < 48 || %char > 102) || (%char > 57 && %char < 97))
|
||||
{
|
||||
// non-hex characters in the challenge!
|
||||
error("TNCommunity: Hostile challenge payload returned by server!");
|
||||
$TribesNext::Community::Challenge = "";
|
||||
tn_community_login_initiate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// challenge is present... decrypt it and transmit it to the community server
|
||||
rubyEval("tsEval '$decryptedChallenge=\"' + $accountKey.decrypt('" @ %challenge @ "'.to_i(16)).to_s(16) + '\";'");
|
||||
|
||||
%verifiedNonce = getSubStr($decryptedChallenge, 0, strLen($TribesNext::Community::Nonce));
|
||||
if (%verifiedNonce !$= $TribesNext::Community::Nonce)
|
||||
{
|
||||
// this is not the nonce we sent to the community server, try again
|
||||
error("TNCommunity: Unmatched nonce in challenge returned by server!");
|
||||
$TribesNext::Community::Challenge = "";
|
||||
tn_community_login_initiate();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
%response = getSubStr($decryptedChallenge, strLen($TribesNext::Community::Nonce), strlen($decryptedChallenge));
|
||||
%payload = %payload @ "response=" @ %response;
|
||||
}
|
||||
}
|
||||
}
|
||||
%payload = %payload @ " HTTP/1.1\r\nHost: " @ $TribesNext::Community::Host @ "\r\nUser-Agent: Tribes 2\r\nConnection: close\r\n\r\n";
|
||||
|
||||
if (isObject(CommunitySessionInterface))
|
||||
{
|
||||
CommunitySessionInterface.disconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
new TCPObject(CommunitySessionInterface);
|
||||
}
|
||||
CommunitySessionInterface.data = %payload;
|
||||
CommunitySessionInterface.connect($TribesNext::Community::Host @ ":" @ $TribesNext::Community::Port);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// TribesNext Project
|
||||
// http://www.tribesnext.com/
|
||||
// Copyright 2011-2017
|
||||
|
||||
// Tribes 2 Community System
|
||||
// Robot Client Settings
|
||||
// Tournament Version
|
||||
|
||||
// This file contains the URL and server settings for the community system.
|
||||
|
||||
$TribesNext::Community::Host = "tribesnext.thyth.com";
|
||||
$TribesNext::Community::Port = 80;
|
||||
$TribesNext::Community::BaseURL = "/tn/robot/";
|
||||
|
||||
$TribesNext::Community::LoginScript = "robot_login.php";
|
||||
$TribesNext::Community::MailScript = "robot_mail.php";
|
||||
$TribesNext::Community::BrowserScript = "robot_browser.php";
|
||||
|
||||
$TribesNext::Community::SessionRefresh = 10*60;
|
||||
Loading…
Add table
Add a link
Reference in a new issue