Initial commit

This commit is contained in:
Eagle517
2025-02-17 23:17:30 -06:00
commit 7cad314c94
4726 changed files with 1145203 additions and 0 deletions

23
example/common/server/audio.cs Executable file
View File

@ -0,0 +1,23 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function ServerPlay2D(%profile)
{
// Play the given sound profile on every client.
// The sounds will be transmitted as an event, not attached to any object.
for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
ClientGroup.getObject(%idx).play2D(%profile);
}
function ServerPlay3D(%profile,%transform)
{
// Play the given sound profile at the given position on every client
// The sound will be transmitted as an event, not attached to any object.
for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
ClientGroup.getObject(%idx).play3D(%profile,%transform);
}

View File

View File

@ -0,0 +1,205 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// This script function is called before a client connection
// is accepted. Returning "" will accept the connection,
// anything else will be sent back as an error to the client.
// All the connect args are passed also to onConnectRequest
//
function GameConnection::onConnectRequest( %client, %netAddress, %name )
{
echo("Connect request from: " @ %netAddress);
if($Server::PlayerCount >= $pref::Server::MaxPlayers)
return "CR_SERVERFULL";
return "";
}
//-----------------------------------------------------------------------------
// This script function is the first called on a client accept
//
function GameConnection::onConnect( %client, %name )
{
// Send down the connection error info, the client is
// responsible for displaying this message if a connection
// error occures.
messageClient(%client,'MsgConnectionError',"",$Pref::Server::ConnectionError);
// Send mission information to the client
sendLoadInfoToClient( %client );
// Simulated client lag for testing...
// %client.setSimulatedNetParams(0.1, 30);
// Get the client's unique id:
// %authInfo = %client.getAuthInfo();
// %client.guid = getField( %authInfo, 3 );
%client.guid = 0;
addToServerGuidList( %client.guid );
// Set admin status
if (%client.getAddress() $= "local") {
%client.isAdmin = true;
%client.isSuperAdmin = true;
}
else {
%client.isAdmin = false;
%client.isSuperAdmin = false;
}
// Save client preferences on the connection object for later use.
%client.gender = "Male";
%client.armor = "Light";
%client.race = "Human";
%client.skin = addTaggedString( "base" );
%client.setPlayerName(%name);
%client.score = 0;
//
$instantGroup = ServerGroup;
$instantGroup = MissionCleanup;
echo("CADD: " @ %client @ " " @ %client.getAddress());
// Inform the client of all the other clients
%count = ClientGroup.getCount();
for (%cl = 0; %cl < %count; %cl++) {
%other = ClientGroup.getObject(%cl);
if ((%other != %client)) {
// These should be "silent" versions of these messages...
messageClient(%client, 'MsgClientJoin', "",
%other.name,
%other,
%other.sendGuid,
%other.score,
%other.isAIControlled(),
%other.isAdmin,
%other.isSuperAdmin);
}
}
// Inform the client we've joined up
messageClient(%client,
'MsgClientJoin', '\c2Welcome to the Torque demo app %1.',
%client.name,
%client,
%client.sendGuid,
%client.score,
%client.isAiControlled(),
%client.isAdmin,
%client.isSuperAdmin);
// Inform all the other clients of the new guy
messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.',
%client.name,
%client,
%client.sendGuid,
%client.score,
%client.isAiControlled(),
%client.isAdmin,
%client.isSuperAdmin);
// If the mission is running, go ahead download it to the client
if ($missionRunning)
%client.loadMission();
$Server::PlayerCount++;
}
//-----------------------------------------------------------------------------
// A player's name could be obtained from the auth server, but for
// now we use the one passed from the client.
// %realName = getField( %authInfo, 0 );
//
function GameConnection::setPlayerName(%client,%name)
{
%client.sendGuid = 0;
// Minimum length requirements
%name = stripTrailingSpaces( strToPlayerName( %name ) );
if ( strlen( %name ) < 3 )
%name = "Poser";
// Make sure the alias is unique, we'll hit something eventually
if (!isNameUnique(%name))
{
%isUnique = false;
for (%suffix = 1; !%isUnique; %suffix++) {
%nameTry = %name @ "." @ %suffix;
%isUnique = isNameUnique(%nameTry);
}
%name = %nameTry;
}
// Tag the name with the "smurf" color:
%client.nameBase = %name;
%client.name = addTaggedString("\cp\c8" @ %name @ "\co");
}
function isNameUnique(%name)
{
%count = ClientGroup.getCount();
for ( %i = 0; %i < %count; %i++ )
{
%test = ClientGroup.getObject( %i );
%rawName = stripChars( detag( getTaggedString( %test.name ) ), "\cp\co\c6\c7\c8\c9" );
if ( strcmp( %name, %rawName ) == 0 )
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// This function is called when a client drops for any reason
//
function GameConnection::onDrop(%client, %reason)
{
%client.onClientLeaveGame();
removeFromServerGuidList( %client.guid );
messageAllExcept(%client, -1, 'MsgClientDrop', '\c1%1 has left the game.', %client.name, %client);
removeTaggedString(%client.name);
echo("CDROP: " @ %client @ " " @ %client.getAddress());
$Server::PlayerCount--;
// Reset the server if everyone has left the game
if( $Server::PlayerCount == 0 && $Server::Dedicated)
schedule(0, 0, "resetServerDefaults");
}
//-----------------------------------------------------------------------------
function GameConnection::startMission(%this)
{
// Inform the client the mission starting
commandToClient(%this, 'MissionStart', $missionSequence);
}
function GameConnection::endMission(%this)
{
// Inform the client the mission is done
commandToClient(%this, 'MissionEnd', $missionSequence);
}
//--------------------------------------------------------------------------
// Sync the clock on the client.
function GameConnection::syncClock(%client, %time)
{
commandToClient(%client, 'syncClock', %time);
}
//--------------------------------------------------------------------------
// Update all the clients with the new score
function GameConnection::incScore(%this,%delta)
{
%this.score += %delta;
messageAll('MsgClientScoreChanged', "", %this.score, %this);
}

View File

@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Misc. server commands avialable to clients
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function serverCmdSAD( %client, %password )
{
if( %password !$= "" && %password $= $Pref::Server::AdminPassword)
{
%client.isAdmin = true;
%client.isSuperAdmin = true;
%name = getTaggedString( %client.name );
MessageAll( 'MsgAdminForce', "\c2" @ %name @ " has become Admin by force.", %client );
}
}
function serverCmdSADSetPassword(%client, %password)
{
if(%client.isSuperAdmin)
$Pref::Server::AdminPassword = %password;
}
//----------------------------------------------------------------------------
// Server chat message handlers
function serverCmdTeamMessageSent(%client, %text)
{
if(strlen(%text) >= $Pref::Server::MaxChatLen)
%text = getSubStr(%text, 0, $Pref::Server::MaxChatLen);
chatMessageTeam(%client, %client.team, '\c3%1: %2', %client.name, %text);
}
function serverCmdMessageSent(%client, %text)
{
if(strlen(%text) >= $Pref::Server::MaxChatLen)
%text = getSubStr(%text, 0, $Pref::Server::MaxChatLen);
chatMessageAll(%client, '\c4%1: %2', %client.name, %text);
}

106
example/common/server/game.cs Executable file
View File

@ -0,0 +1,106 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Invoked from the common server & mission loading functions
//-----------------------------------------------------------------------------
function onServerCreated()
{
// Invoked by createServer(), when server is created and ready to go
// Server::GameType is sent to the master server.
// This variable should uniquely identify your game and/or mod.
$Server::GameType = "Test App";
// Server::MissionType sent to the master server. Clients can
// filter servers based on mission type.
$Server::MissionType = "Deathmatch";
// Load up all datablocks, objects etc. This function is called when
// a server is constructed.
// exec("./foo.cs");
// For backwards compatibility...
createGame();
}
function onServerDestroyed()
{
// Invoked by destroyServer(), right before the server is destroyed
destroyGame();
}
function onMissionLoaded()
{
// Called by loadMission() once the mission is finished loading
startGame();
}
function onMissionEnded()
{
// Called by endMission(), right before the mission is destroyed
endGame();
}
function onMissionReset()
{
// Called by resetMission(), after all the temporary mission objects
// have been deleted.
}
//-----------------------------------------------------------------------------
// These methods are extensions to the GameConnection class. Extending
// GameConnection make is easier to deal with some of this functionality,
// but these could also be implemented as stand-alone functions.
//-----------------------------------------------------------------------------
function GameConnection::onClientEnterGame(%this)
{
// Called for each client after it's finished downloading the
// mission and is ready to start playing.
// Tg: Should think about renaming this onClientEnterMission
}
function GameConnection::onClientLeaveGame(%this)
{
// Call for each client that drops
// Tg: Should think about renaming this onClientLeaveMission
}
//-----------------------------------------------------------------------------
// Functions that implement game-play
// These are here for backwards compatibilty only, games and/or mods should
// really be overloading the server and mission functions listed ubove.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function createGame()
{
// This function is called by onServerCreated (ubove)
}
function destroyGame()
{
// This function is called by onServerDestroyed (ubove)
}
//-----------------------------------------------------------------------------
function startGame()
{
// This is where the game play should start
// The default onMissionLoaded function starts the game.
}
function endGame()
{
// This is where the game play should end
// The default onMissionEnded function shuts down the game.
}

View File

@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function kick(%client)
{
messageAll( 'MsgAdminForce', '\c2The Admin has kicked %1.', %client.name);
if (!%client.isAIControlled())
BanList::add(%client.guid, %client.getAddress(), $Pref::Server::KickBanTime);
%client.delete("You have been kicked from this server");
}
function ban(%client)
{
messageAll('MsgAdminForce', '\c2The Admin has banned %1.', %client.name);
if (!%client.isAIControlled())
BanList::add(%client.guid, %client.getAddress(), $Pref::Server::BanTime);
%client.delete("You have been banned from this server");
}

154
example/common/server/message.cs Executable file
View File

@ -0,0 +1,154 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Server side message commands
//-----------------------------------------------------------------------------
function messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13)
{
commandToClient(%client, 'ServerMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);
}
function messageTeam(%team, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13)
{
%count = ClientGroup.getCount();
for(%cl= 0; %cl < %count; %cl++)
{
%recipient = ClientGroup.getObject(%cl);
if(%recipient.team == %team)
messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);
}
}
function messageTeamExcept(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13)
{
%team = %client.team;
%count = ClientGroup.getCount();
for(%cl= 0; %cl < %count; %cl++)
{
%recipient = ClientGroup.getObject(%cl);
if((%recipient.team == %team) && (%recipient != %client))
messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);
}
}
function messageAll(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13)
{
%count = ClientGroup.getCount();
for(%cl = 0; %cl < %count; %cl++)
{
%client = ClientGroup.getObject(%cl);
messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);
}
}
function messageAllExcept(%client, %team, %msgtype, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13)
{
//can exclude a client, a team or both. A -1 value in either field will ignore that exclusion, so
//messageAllExcept(-1, -1, $Mesblah, 'Blah!'); will message everyone (since there shouldn't be a client -1 or client on team -1).
%count = ClientGroup.getCount();
for(%cl= 0; %cl < %count; %cl++)
{
%recipient = ClientGroup.getObject(%cl);
if((%recipient != %client) && (%recipient.team != %team))
messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);
}
}
//---------------------------------------------------------------------------
// Server side client chat'n
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// silly spam protection...
$SPAM_PROTECTION_PERIOD = 10000;
$SPAM_MESSAGE_THRESHOLD = 4;
$SPAM_PENALTY_PERIOD = 10000;
$SPAM_MESSAGE = '\c3FLOOD PROTECTION:\cr You must wait another %1 seconds.';
function GameConnection::spamMessageTimeout(%this)
{
if(%this.spamMessageCount > 0)
%this.spamMessageCount--;
}
function GameConnection::spamReset(%this)
{
%this.isSpamming = false;
}
function spamAlert(%client)
{
if($Pref::Server::FloodProtectionEnabled != true)
return(false);
if(!%client.isSpamming && (%client.spamMessageCount >= $SPAM_MESSAGE_THRESHOLD))
{
%client.spamProtectStart = getSimTime();
%client.isSpamming = true;
%client.schedule($SPAM_PENALTY_PERIOD, spamReset);
}
if(%client.isSpamming)
{
%wait = mFloor(($SPAM_PENALTY_PERIOD - (getSimTime() - %client.spamProtectStart)) / 1000);
messageClient(%client, "", $SPAM_MESSAGE, %wait);
return(true);
}
%client.spamMessageCount++;
%client.schedule($SPAM_PROTECTION_PERIOD, spamMessageTimeout);
return(false);
}
//---------------------------------------------------------------------------
function chatMessageClient( %client, %sender, %voiceTag, %voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 )
{
//see if the client has muted the sender
if ( !%client.muted[%sender] )
commandToClient( %client, 'ChatMessage', %sender, %voiceTag, %voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );
}
function chatMessageTeam( %sender, %team, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 )
{
if ( ( %msgString $= "" ) || spamAlert( %sender ) )
return;
%count = ClientGroup.getCount();
for ( %i = 0; %i < %count; %i++ )
{
%obj = ClientGroup.getObject( %i );
if ( %obj.team == %sender.team )
chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );
}
}
function chatMessageAll( %sender, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 )
{
if ( ( %msgString $= "" ) || spamAlert( %sender ) )
return;
%count = ClientGroup.getCount();
for ( %i = 0; %i < %count; %i++ )
{
%obj = ClientGroup.getObject( %i );
if(%sender.team != 0)
chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );
else
{
// message sender is an observer -- only send message to other observers
if(%obj.team == %sender.team)
chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );
}
}
}

View File

@ -0,0 +1,117 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Mission Loading
// The server portion of the client/server mission loading process
//-----------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Loading Phases:
// Phase 1: Transmit Datablocks
// Transmit targets
// Phase 2: Transmit Ghost Objects
// Phase 3: Start Game
//
// The server invokes the client MissionStartPhase[1-3] function to request
// permission to start each phase. When a client is ready for a phase,
// it responds with MissionStartPhase[1-3]Ack.
function GameConnection::loadMission(%this)
{
// Send over the information that will display the server info
// when we learn it got there, we'll send the data blocks
%this.currentPhase = 0;
if (%this.isAIControlled())
{
// Cut to the chase...
%this.onClientEnterGame();
}
else
{
commandToClient(%this, 'MissionStartPhase1', $missionSequence,
$Server::MissionFile, MissionGroup.musicTrack);
echo("*** Sending mission load to client: " @ $Server::MissionFile);
}
}
function serverCmdMissionStartPhase1Ack(%client, %seq)
{
// Make sure to ignore calls from a previous mission load
if (%seq != $missionSequence || !$MissionRunning)
return;
if (%client.currentPhase != 0)
return;
%client.currentPhase = 1;
// Start with the CRC
%client.setMissionCRC( $missionCRC );
// Send over the datablocks...
// OnDataBlocksDone will get called when have confirmation
// that they've all been received.
%client.transmitDataBlocks($missionSequence);
}
function GameConnection::onDataBlocksDone( %this, %missionSequence )
{
// Make sure to ignore calls from a previous mission load
if (%missionSequence != $missionSequence)
return;
if (%this.currentPhase != 1)
return;
%this.currentPhase = 1.5;
// On to the next phase
commandToClient(%this, 'MissionStartPhase2', $missionSequence, $Server::MissionFile);
}
function serverCmdMissionStartPhase2Ack(%client, %seq)
{
// Make sure to ignore calls from a previous mission load
if (%seq != $missionSequence || !$MissionRunning)
return;
if (%client.currentPhase != 1.5)
return;
%client.currentPhase = 2;
// Update mod paths, this needs to get there before the objects.
%client.transmitPaths();
// Start ghosting objects to the client
%client.activateGhosting();
}
function GameConnection::clientWantsGhostAlwaysRetry(%client)
{
if($MissionRunning)
%client.activateGhosting();
}
function GameConnection::onGhostAlwaysFailed(%client)
{
}
function GameConnection::onGhostAlwaysObjectsReceived(%client)
{
// Ready for next phase.
commandToClient(%client, 'MissionStartPhase3', $missionSequence, $Server::MissionFile);
}
function serverCmdMissionStartPhase3Ack(%client, %seq)
{
// Make sure to ignore calls from a previous mission load
if(%seq != $missionSequence || !$MissionRunning)
return;
if(%client.currentPhase != 2)
return;
%client.currentPhase = 3;
// Server is ready to drop into the game
%client.startMission();
%client.onClientEnterGame();
}

View File

@ -0,0 +1,88 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Loading info is text displayed on the client side while the mission
// is being loaded. This information is extracted from the mission file
// and sent to each the client as it joins.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// clearLoadInfo
//
// Clears the mission info stored
//------------------------------------------------------------------------------
function clearLoadInfo() {
if (isObject(MissionInfo))
MissionInfo.delete();
}
//------------------------------------------------------------------------------
// buildLoadInfo
//
// Extract the map description from the .mis file
//------------------------------------------------------------------------------
function buildLoadInfo( %mission ) {
clearLoadInfo();
%infoObject = "";
%file = new FileObject();
if ( %file.openForRead( %mission ) ) {
%inInfoBlock = false;
while ( !%file.isEOF() ) {
%line = %file.readLine();
%line = trim( %line );
if( %line $= "new ScriptObject(MissionInfo) {" )
%inInfoBlock = true;
else if( %inInfoBlock && %line $= "};" ) {
%inInfoBlock = false;
%infoObject = %infoObject @ %line;
break;
}
if( %inInfoBlock )
%infoObject = %infoObject @ %line @ " ";
}
%file.close();
}
// Will create the object "MissionInfo"
eval( %infoObject );
%file.delete();
}
//------------------------------------------------------------------------------
// dumpLoadInfo
//
// Echo the mission information to the console
//------------------------------------------------------------------------------
function dumpLoadInfo()
{
echo( "Mission Name: " @ MissionInfo.name );
echo( "Mission Description:" );
for( %i = 0; MissionInfo.desc[%i] !$= ""; %i++ )
echo (" " @ MissionInfo.desc[%i]);
}
//------------------------------------------------------------------------------
// sendLoadInfoToClient
//
// Sends mission description to the client
//------------------------------------------------------------------------------
function sendLoadInfoToClient( %client )
{
messageClient( %client, 'MsgLoadInfo', "", MissionInfo.name );
// Send Mission Description a line at a time
for( %i = 0; MissionInfo.desc[%i] !$= ""; %i++ )
messageClient( %client, 'MsgLoadDescripition', "", MissionInfo.desc[%i] );
messageClient( %client, 'MsgLoadInfoDone' );
}

View File

@ -0,0 +1,147 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Server mission loading
//-----------------------------------------------------------------------------
// On every mission load except the first, there is a pause after
// the initial mission info is downloaded to the client.
$MissionLoadPause = 5000;
//-----------------------------------------------------------------------------
function loadMission( %missionName, %isFirstMission )
{
endMission();
echo("*** LOADING MISSION: " @ %missionName);
echo("*** Stage 1 load");
// Reset all of these
clearCenterPrintAll();
clearBottomPrintAll();
// increment the mission sequence (used for ghost sequencing)
$missionSequence++;
$missionRunning = false;
$Server::MissionFile = %missionName;
// Extract mission info from the mission file,
// including the display name and stuff to send
// to the client.
buildLoadInfo( %missionName );
// Download mission info to the clients
%count = ClientGroup.getCount();
for( %cl = 0; %cl < %count; %cl++ ) {
%client = ClientGroup.getObject( %cl );
if (!%client.isAIControlled())
sendLoadInfoToClient(%client);
}
// if this isn't the first mission, allow some time for the server
// to transmit information to the clients:
if( %isFirstMission || $Server::ServerType $= "SinglePlayer" )
loadMissionStage2();
else
schedule( $MissionLoadPause, ServerGroup, loadMissionStage2 );
}
//-----------------------------------------------------------------------------
function loadMissionStage2()
{
// Create the mission group off the ServerGroup
echo("*** Stage 2 load");
$instantGroup = ServerGroup;
// Make sure the mission exists
%file = $Server::MissionFile;
if( !isFile( %file ) ) {
error( "Could not find mission " @ %file );
return;
}
// Calculate the mission CRC. The CRC is used by the clients
// to caching mission lighting.
$missionCRC = getFileCRC( %file );
// Exec the mission, objects are added to the ServerGroup
exec(%file);
// If there was a problem with the load, let's try another mission
if( !isObject(MissionGroup) ) {
error( "No 'MissionGroup' found in mission \"" @ $missionName @ "\"." );
schedule( 3000, ServerGroup, CycleMissions );
return;
}
// Mission cleanup group
new SimGroup( MissionCleanup );
$instantGroup = MissionCleanup;
// Construct MOD paths
pathOnMissionLoadDone();
// Mission loading done...
echo("*** Mission loaded");
// Start all the clients in the mission
$missionRunning = true;
for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ )
ClientGroup.getObject(%clientIndex).loadMission();
// Go ahead and launch the game
onMissionLoaded();
purgeResources();
}
//-----------------------------------------------------------------------------
function endMission()
{
if (!isObject( MissionGroup ))
return;
echo("*** ENDING MISSION");
// Inform the game code we're done.
onMissionEnded();
// Inform the clients
for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) {
// clear ghosts and paths from all clients
%cl = ClientGroup.getObject( %clientIndex );
%cl.endMission();
%cl.resetGhosting();
%cl.clearPaths();
}
// Delete everything
MissionGroup.delete();
MissionCleanup.delete();
$ServerGroup.delete();
$ServerGroup = new SimGroup(ServerGroup);
}
//-----------------------------------------------------------------------------
function resetMission()
{
echo("*** MISSION RESET");
// Remove any temporary mission objects
MissionCleanup.delete();
$instantGroup = ServerGroup;
new SimGroup( MissionCleanup );
$instantGroup = MissionCleanup;
//
onMissionReset();
}

148
example/common/server/server.cs Executable file
View File

@ -0,0 +1,148 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function portInit(%port)
{
%failCount = 0;
while(%failCount < 10 && !setNetPort(%port)) {
echo("Port init failed on port " @ %port @ " trying next port.");
%port++; %failCount++;
}
}
function createServer(%serverType, %mission)
{
if (%mission $= "") {
error("createServer: mission name unspecified");
return;
}
destroyServer();
//
$missionSequence = 0;
$Server::PlayerCount = 0;
$Server::ServerType = %serverType;
// Setup for multi-player, the network must have been
// initialized before now.
if (%serverType $= "MultiPlayer") {
echo("Starting multiplayer mode");
// Make sure the network port is set to the correct pref.
portInit($Pref::Server::Port);
allowConnections(true);
if ($pref::Net::DisplayOnMaster !$= "Never" )
schedule(0,0,startHeartbeat);
}
// Load the mission
$ServerGroup = new SimGroup(ServerGroup);
onServerCreated();
loadMission(%mission, true);
}
//-----------------------------------------------------------------------------
function destroyServer()
{
$Server::ServerType = "";
allowConnections(false);
stopHeartbeat();
$missionRunning = false;
// End any running mission
endMission();
onServerDestroyed();
// Delete all the server objects
if (isObject(MissionGroup))
MissionGroup.delete();
if (isObject(MissionCleanup))
MissionCleanup.delete();
if (isObject($ServerGroup))
$ServerGroup.delete();
// Delete all the connections:
while (ClientGroup.getCount())
{
%client = ClientGroup.getObject(0);
%client.delete();
}
$Server::GuidList = "";
// Delete all the data blocks...
deleteDataBlocks();
// Save any server settings
echo( "Exporting server prefs..." );
export( "$Pref::Server::*", "~/prefs.cs", false );
// Dump anything we're not using
purgeResources();
}
//--------------------------------------------------------------------------
function resetServerDefaults()
{
echo( "Resetting server defaults..." );
// Override server defaults with prefs:
exec( "~/defaults.cs" );
exec( "~/prefs.cs" );
loadMission( $Server::MissionFile );
}
//------------------------------------------------------------------------------
// Guid list maintenance functions:
function addToServerGuidList( %guid )
{
%count = getFieldCount( $Server::GuidList );
for ( %i = 0; %i < %count; %i++ )
{
if ( getField( $Server::GuidList, %i ) == %guid )
return;
}
$Server::GuidList = $Server::GuidList $= "" ? %guid : $Server::GuidList TAB %guid;
}
function removeFromServerGuidList( %guid )
{
%count = getFieldCount( $Server::GuidList );
for ( %i = 0; %i < %count; %i++ )
{
if ( getField( $Server::GuidList, %i ) == %guid )
{
$Server::GuidList = removeField( $Server::GuidList, %i );
return;
}
}
// Huh, didn't find it.
}
//-----------------------------------------------------------------------------
function onServerInfoQuery()
{
// When the server is queried for information, the value
// of this function is returned as the status field of
// the query packet. This information is accessible as
// the ServerInfo::State variable.
return "Doing Ok";
}