2004-03-16 22:34:48 +00:00
|
|
|
#include "global.h"
|
|
|
|
|
#include "NetworkSyncManager.h"
|
2004-06-15 02:21:16 +00:00
|
|
|
|
|
|
|
|
NetworkSyncManager *NSMAN;
|
|
|
|
|
|
2004-06-20 17:42:58 +00:00
|
|
|
#if defined(WITHOUT_NETWORKING)
|
2004-06-15 02:21:16 +00:00
|
|
|
NetworkSyncManager::NetworkSyncManager() { }
|
|
|
|
|
NetworkSyncManager::~NetworkSyncManager () { }
|
|
|
|
|
void NetworkSyncManager::CloseConnection() { }
|
|
|
|
|
void NetworkSyncManager::PostStartUp( CString ServerIP ) { }
|
|
|
|
|
bool NetworkSyncManager::Connect(const CString& addy, unsigned short port) { return false; }
|
|
|
|
|
void NetworkSyncManager::ReportScore(int playerID, int step, int score, int combo) { }
|
|
|
|
|
void NetworkSyncManager::ReportSongOver() { }
|
|
|
|
|
void NetworkSyncManager::StartRequest() { }
|
|
|
|
|
void NetworkSyncManager::SendSongs() { }
|
|
|
|
|
void NetworkSyncManager::DisplayStartupStatus() { }
|
|
|
|
|
void NetworkSyncManager::Update( float fDeltaTime ) { }
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
#include "ezsockets.h"
|
2004-04-14 20:39:58 +00:00
|
|
|
#include "ProfileManager.h"
|
2004-03-16 22:34:48 +00:00
|
|
|
#include "RageLog.h"
|
2004-04-15 20:21:39 +00:00
|
|
|
#include "StepMania.h"
|
2004-04-14 20:39:58 +00:00
|
|
|
#include "RageUtil.h"
|
2004-04-17 22:26:37 +00:00
|
|
|
#include "ThemeManager.h"
|
2004-04-29 01:03:28 +00:00
|
|
|
#include "Screen.h"
|
2004-04-17 22:26:37 +00:00
|
|
|
#include "PlayerNumber.h"
|
|
|
|
|
#include "GameConstantsAndTypes.h"
|
|
|
|
|
#include "SongOptions.h"
|
|
|
|
|
#include "ScreenManager.h"
|
|
|
|
|
#include "Course.h"
|
2004-04-17 23:09:15 +00:00
|
|
|
#include "song.h"
|
2004-04-17 22:26:37 +00:00
|
|
|
#include "SongManager.h"
|
|
|
|
|
#include "GameState.h"
|
2004-05-05 03:46:28 +00:00
|
|
|
#include "StageStats.h"
|
|
|
|
|
#include "Steps.h"
|
2004-04-15 20:21:39 +00:00
|
|
|
|
2004-04-15 15:31:59 +00:00
|
|
|
NetworkSyncManager::NetworkSyncManager()
|
2004-03-16 22:34:48 +00:00
|
|
|
{
|
2004-03-17 06:05:52 +00:00
|
|
|
NetPlayerClient = new EzSockets;
|
2004-03-25 15:08:07 +00:00
|
|
|
m_ServerVersion = 0;
|
2004-04-15 15:31:59 +00:00
|
|
|
|
|
|
|
|
useSMserver = false;
|
2004-04-29 01:03:28 +00:00
|
|
|
m_startupStatus = 0; //By default, connection not tried.
|
2004-03-25 15:08:07 +00:00
|
|
|
|
2004-04-15 20:21:39 +00:00
|
|
|
StartUp();
|
2004-04-15 15:31:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NetworkSyncManager::~NetworkSyncManager ()
|
|
|
|
|
{
|
|
|
|
|
//Close Connection to server nicely.
|
|
|
|
|
if (useSMserver)
|
|
|
|
|
NetPlayerClient->close();
|
|
|
|
|
delete NetPlayerClient;
|
|
|
|
|
}
|
2004-04-14 20:39:58 +00:00
|
|
|
|
2004-04-30 04:34:39 +00:00
|
|
|
void NetworkSyncManager::CloseConnection()
|
2004-04-15 15:31:59 +00:00
|
|
|
{
|
2004-04-30 04:34:39 +00:00
|
|
|
if (!useSMserver)
|
|
|
|
|
return ;
|
|
|
|
|
m_ServerVersion = 0;
|
|
|
|
|
useSMserver = false;
|
|
|
|
|
m_startupStatus = 0;
|
|
|
|
|
NetPlayerClient->close();
|
|
|
|
|
}
|
2004-04-29 01:03:28 +00:00
|
|
|
|
2004-04-30 04:34:39 +00:00
|
|
|
void NetworkSyncManager::PostStartUp(CString ServerIP)
|
|
|
|
|
{
|
|
|
|
|
CloseConnection();
|
|
|
|
|
if( ServerIP!="LISTEN" )
|
2004-04-15 20:21:39 +00:00
|
|
|
{
|
2004-05-25 10:39:23 +00:00
|
|
|
if( !Connect(ServerIP.c_str(), 8765) )
|
2004-04-15 15:31:59 +00:00
|
|
|
{
|
2004-04-29 01:03:28 +00:00
|
|
|
m_startupStatus = 2;
|
2004-04-15 20:21:39 +00:00
|
|
|
LOG->Warn( "Network Sync Manager failed to connect" );
|
|
|
|
|
return;
|
2004-04-14 20:39:58 +00:00
|
|
|
}
|
2004-04-15 20:21:39 +00:00
|
|
|
|
2004-04-30 04:34:39 +00:00
|
|
|
} else {
|
2004-04-15 20:21:39 +00:00
|
|
|
if( !Listen(8765) )
|
|
|
|
|
{
|
2004-04-29 01:03:28 +00:00
|
|
|
m_startupStatus = 2;
|
2004-05-25 10:39:23 +00:00
|
|
|
LOG->Warn( "Listen() failed" );
|
2004-04-15 20:21:39 +00:00
|
|
|
return;
|
2004-04-14 20:39:58 +00:00
|
|
|
}
|
2004-04-15 20:21:39 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
useSMserver = true;
|
|
|
|
|
|
2004-04-29 01:03:28 +00:00
|
|
|
m_startupStatus = 1; //Connection attepmpt sucessful
|
2004-05-24 13:59:05 +00:00
|
|
|
LOG->Info("CNConnected!");
|
2004-04-15 20:21:39 +00:00
|
|
|
int ClientCommand=3;
|
2004-05-24 13:59:05 +00:00
|
|
|
NetPlayerClient->SendPack((char*) &ClientCommand, 4);
|
|
|
|
|
LOG->Info("CNCHECKPOINT");
|
|
|
|
|
|
2004-05-25 10:39:23 +00:00
|
|
|
NetPlayerClient->ReadData((char*)&m_ServerVersion, 4);
|
|
|
|
|
LOG->Info("CNCHECKPOINT:%d", int(NetPlayerClient->inBuffer.length()));
|
2004-04-15 20:21:39 +00:00
|
|
|
|
|
|
|
|
// If network play is desired and the connection works,
|
|
|
|
|
// halt until we know what server version we're dealing with
|
|
|
|
|
vector <CString> ProfileNames;
|
|
|
|
|
PROFILEMAN->GetLocalProfileNames(ProfileNames);
|
|
|
|
|
|
|
|
|
|
netName PlayerName;
|
|
|
|
|
if( ProfileNames.size() > 0 )
|
|
|
|
|
{
|
|
|
|
|
PlayerName.m_packID = 30;
|
2004-04-17 23:09:15 +00:00
|
|
|
unsigned i;
|
|
|
|
|
for( i=0; i < strlen(ProfileNames[0]); i++ )
|
2004-04-15 20:21:39 +00:00
|
|
|
PlayerName.m_data[i] = ProfileNames[0][i];
|
2004-04-17 22:26:37 +00:00
|
|
|
PlayerName.m_data[i] = 0;
|
2004-05-25 10:39:23 +00:00
|
|
|
NetPlayerClient->SendPack((char*)&PlayerName, 20);
|
2004-04-15 20:21:39 +00:00
|
|
|
}
|
|
|
|
|
if( ProfileNames.size() > 1 )
|
|
|
|
|
{
|
|
|
|
|
PlayerName.m_packID = 31;
|
2004-04-17 23:09:15 +00:00
|
|
|
unsigned i=0;
|
|
|
|
|
for( i=0; i < strlen(ProfileNames[1]); i++ )
|
2004-04-15 20:21:39 +00:00
|
|
|
PlayerName.m_data[i] = ProfileNames[1][i];
|
2004-04-17 22:26:37 +00:00
|
|
|
PlayerName.m_data[i] = 0;
|
2004-05-25 10:39:23 +00:00
|
|
|
NetPlayerClient->SendPack( (char*)&PlayerName, 20 );
|
2004-04-15 20:21:39 +00:00
|
|
|
}
|
|
|
|
|
|
2004-05-25 10:39:23 +00:00
|
|
|
LOG->Info("Server Version: %d", m_ServerVersion);
|
2004-03-16 22:34:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-04-30 04:34:39 +00:00
|
|
|
void NetworkSyncManager::StartUp()
|
|
|
|
|
{
|
|
|
|
|
CString ServerIP;
|
|
|
|
|
|
|
|
|
|
if( GetCommandlineArgument( "netip", &ServerIP ) )
|
|
|
|
|
PostStartUp(ServerIP);
|
|
|
|
|
else if( GetCommandlineArgument( "listen" ) )
|
|
|
|
|
PostStartUp("LISTEN");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-03-17 13:31:42 +00:00
|
|
|
bool NetworkSyncManager::Connect(const CString& addy, unsigned short port)
|
2004-03-16 22:34:48 +00:00
|
|
|
{
|
2004-03-30 20:13:22 +00:00
|
|
|
LOG->Info("Beginning to connect");
|
2004-05-25 10:39:23 +00:00
|
|
|
if (port != 8765)
|
2004-03-17 13:31:42 +00:00
|
|
|
return false;
|
2004-03-16 22:34:48 +00:00
|
|
|
//Make sure using port 8765
|
|
|
|
|
//This may change in future versions
|
|
|
|
|
//It is this way now for protocol's purpose.
|
|
|
|
|
//If there is a new protocol developed down the road
|
|
|
|
|
|
2004-03-17 13:38:48 +00:00
|
|
|
NetPlayerClient->create(); // Initilize Socket
|
2004-03-17 13:31:42 +00:00
|
|
|
useSMserver = NetPlayerClient->connect(addy, port);
|
|
|
|
|
|
|
|
|
|
return useSMserver;
|
2004-03-16 22:34:48 +00:00
|
|
|
}
|
|
|
|
|
|
2004-03-30 20:13:22 +00:00
|
|
|
|
|
|
|
|
//Listen (Wait for connection in-bound)
|
|
|
|
|
//NOTE: Right now, StepMania cannot connect back to StepMania!
|
|
|
|
|
|
|
|
|
|
bool NetworkSyncManager::Listen(unsigned short port)
|
|
|
|
|
{
|
|
|
|
|
LOG->Info("Beginning to Listen");
|
2004-05-25 10:39:23 +00:00
|
|
|
if (port != 8765)
|
2004-03-30 20:13:22 +00:00
|
|
|
return false;
|
|
|
|
|
//Make sure using port 8765
|
|
|
|
|
//This may change in future versions
|
|
|
|
|
//It is this way now for protocol's purpose.
|
|
|
|
|
//If there is a new protocol developed down the road
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EzSockets * EZListener = new EzSockets;
|
|
|
|
|
|
|
|
|
|
EZListener->create();
|
|
|
|
|
NetPlayerClient->create(); // Initilize Socket
|
|
|
|
|
|
|
|
|
|
EZListener->bind(8765);
|
|
|
|
|
|
|
|
|
|
useSMserver = EZListener->listen();
|
2004-05-25 10:39:23 +00:00
|
|
|
useSMserver = EZListener->accept( *NetPlayerClient ); //Wait for someone to connect
|
2004-03-30 20:13:22 +00:00
|
|
|
|
|
|
|
|
EZListener->close(); //Kill Listener
|
|
|
|
|
delete EZListener;
|
|
|
|
|
|
2004-03-31 04:18:44 +00:00
|
|
|
//LOG->Info("Accept Responce: ",useSMserver);
|
2004-03-30 20:13:22 +00:00
|
|
|
useSMserver=true;
|
|
|
|
|
return useSMserver;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2004-03-17 06:05:52 +00:00
|
|
|
void NetworkSyncManager::ReportScore(int playerID, int step, int score, int combo)
|
2004-03-16 22:34:48 +00:00
|
|
|
{
|
2004-03-17 13:31:42 +00:00
|
|
|
if (!useSMserver) //Make sure that we are using the network
|
2004-03-17 06:05:52 +00:00
|
|
|
return;
|
2004-03-16 22:34:48 +00:00
|
|
|
|
|
|
|
|
netHolder SendNetPack; //Create packet to send to server
|
|
|
|
|
|
|
|
|
|
SendNetPack.m_playerID = playerID;
|
|
|
|
|
SendNetPack.m_combo=combo;
|
2004-03-30 07:43:12 +00:00
|
|
|
SendNetPack.m_score=score; //Load packet with appropriate info
|
2004-03-16 22:34:48 +00:00
|
|
|
SendNetPack.m_step=step-1;
|
2004-05-05 05:41:51 +00:00
|
|
|
|
|
|
|
|
int CurGrade = g_CurStageStats.GetGrade((PlayerNumber)playerID);
|
|
|
|
|
|
|
|
|
|
//Should be cleaned up
|
|
|
|
|
SendNetPack.m_life=m_playerLife[playerID] + CurGrade*65536;
|
2004-03-16 22:34:48 +00:00
|
|
|
|
2004-03-17 06:05:52 +00:00
|
|
|
//Send packet to server
|
2004-05-24 13:59:05 +00:00
|
|
|
NetPlayerClient->SendPack((char*)&SendNetPack, sizeof(netHolder));
|
2004-03-30 05:50:36 +00:00
|
|
|
|
2004-03-16 22:34:48 +00:00
|
|
|
}
|
2004-03-31 04:18:44 +00:00
|
|
|
|
2004-03-16 22:34:48 +00:00
|
|
|
|
2004-03-17 06:05:52 +00:00
|
|
|
void NetworkSyncManager::ReportSongOver()
|
2004-03-16 22:34:48 +00:00
|
|
|
{
|
2004-03-17 13:31:42 +00:00
|
|
|
if (!useSMserver) //Make sure that we are using the network
|
2004-03-16 22:34:48 +00:00
|
|
|
return ;
|
|
|
|
|
|
|
|
|
|
netHolder SendNetPack; //Create packet to send to server
|
|
|
|
|
|
2004-03-30 07:43:12 +00:00
|
|
|
SendNetPack.m_playerID = 21; // Song over Packet player ID
|
2004-05-05 03:46:28 +00:00
|
|
|
|
|
|
|
|
|
2004-05-05 05:41:51 +00:00
|
|
|
SendNetPack.m_step=0;
|
2004-05-05 03:46:28 +00:00
|
|
|
SendNetPack.m_score=0;
|
|
|
|
|
SendNetPack.m_combo=0;
|
2004-03-30 05:50:36 +00:00
|
|
|
SendNetPack.m_life=0;
|
2004-03-16 22:34:48 +00:00
|
|
|
|
2004-03-30 05:50:36 +00:00
|
|
|
|
2004-05-24 13:59:05 +00:00
|
|
|
NetPlayerClient->SendPack((char*)&SendNetPack, sizeof(netHolder));
|
2004-03-16 22:34:48 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-17 06:05:52 +00:00
|
|
|
void NetworkSyncManager::StartRequest()
|
2004-03-16 22:34:48 +00:00
|
|
|
{
|
2004-03-17 13:31:42 +00:00
|
|
|
if (!useSMserver)
|
2004-03-16 22:34:48 +00:00
|
|
|
return ;
|
|
|
|
|
|
2004-04-28 01:25:44 +00:00
|
|
|
//If it's going into demonstration (or jukebox) mode, do not
|
|
|
|
|
//bother to sync.
|
|
|
|
|
if (GAMESTATE->m_bDemonstrationOrJukebox)
|
|
|
|
|
return ;
|
|
|
|
|
|
|
|
|
|
|
2004-05-24 13:59:05 +00:00
|
|
|
char tmp[4]; //Temporary vector used by receive function when waiting
|
2004-03-16 22:34:48 +00:00
|
|
|
|
2004-04-17 03:28:31 +00:00
|
|
|
LOG->Trace("Requesting Start from Server.");
|
2004-03-16 22:34:48 +00:00
|
|
|
|
|
|
|
|
netHolder SendNetPack;
|
|
|
|
|
|
2004-03-30 07:43:12 +00:00
|
|
|
SendNetPack.m_playerID = 20; // Song Start Request Packet player ID
|
2004-05-05 03:46:28 +00:00
|
|
|
|
|
|
|
|
//Report Step difficulties
|
|
|
|
|
|
|
|
|
|
Steps * tSteps;
|
2004-05-08 06:38:27 +00:00
|
|
|
SendNetPack.m_step = 0;
|
2004-05-05 03:46:28 +00:00
|
|
|
tSteps = g_CurStageStats.pSteps[PLAYER_1];
|
|
|
|
|
if (tSteps!=NULL)
|
|
|
|
|
{
|
2004-05-25 10:39:23 +00:00
|
|
|
SendNetPack.m_step = tSteps->GetMeter();
|
2004-05-05 03:46:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tSteps = g_CurStageStats.pSteps[PLAYER_2];
|
|
|
|
|
if (tSteps!=NULL)
|
|
|
|
|
{
|
2004-05-25 10:39:23 +00:00
|
|
|
SendNetPack.m_step += tSteps->GetMeter()*256;
|
2004-05-05 03:46:28 +00:00
|
|
|
}
|
|
|
|
|
SendNetPack.m_score = 0;
|
2004-05-25 10:39:23 +00:00
|
|
|
SendNetPack.m_life = 0;
|
|
|
|
|
SendNetPack.m_combo = 0;
|
2004-03-16 22:34:48 +00:00
|
|
|
|
2004-05-24 13:59:05 +00:00
|
|
|
NetPlayerClient->SendPack((char*)&SendNetPack, sizeof(netHolder));
|
2004-03-16 22:34:48 +00:00
|
|
|
|
2004-04-17 03:28:31 +00:00
|
|
|
LOG->Trace("Waiting for RECV");
|
2004-03-16 22:34:48 +00:00
|
|
|
|
|
|
|
|
//Block until go is recieved.
|
2004-05-24 13:59:05 +00:00
|
|
|
NetPlayerClient->ReadData((char *)tmp, 4);
|
2004-03-16 22:34:48 +00:00
|
|
|
|
2004-04-17 03:28:31 +00:00
|
|
|
LOG->Trace("Starting Game.");
|
2004-03-17 04:15:36 +00:00
|
|
|
}
|
|
|
|
|
|
2004-04-17 22:26:37 +00:00
|
|
|
//This must be executed after NSMAN was started.
|
|
|
|
|
|
|
|
|
|
//this is for use with SMOnline.
|
|
|
|
|
//In order to gaurentee song title and group names
|
|
|
|
|
//line up, SM will be started and load, and then
|
|
|
|
|
//send all info to the local client.
|
|
|
|
|
//This information will be then relayed to the
|
|
|
|
|
//SMOnline server.
|
|
|
|
|
void NetworkSyncManager::SendSongs()
|
|
|
|
|
{
|
2004-04-29 01:03:28 +00:00
|
|
|
if (!useSMserver)
|
|
|
|
|
return ;
|
|
|
|
|
|
2004-04-17 22:26:37 +00:00
|
|
|
vector <Song *> LogSongs;
|
|
|
|
|
LogSongs = SONGMAN->GetAllSongs();
|
2004-04-17 23:09:15 +00:00
|
|
|
unsigned i,j;
|
2004-04-17 22:26:37 +00:00
|
|
|
CString SongInfo;
|
|
|
|
|
char toSend[1020]; //Standard buffer is 1024 and
|
|
|
|
|
//we have to include 4 size bytes
|
2004-05-25 10:39:23 +00:00
|
|
|
for (i=0; i<LogSongs.size(); i++)
|
2004-04-17 22:26:37 +00:00
|
|
|
{
|
|
|
|
|
Song * CSong = LogSongs[i];
|
2004-05-25 10:39:23 +00:00
|
|
|
SongInfo = char(1) + CSong->m_sGroupName;
|
|
|
|
|
SongInfo += char(2) + CSong->GetTranslitMainTitle();
|
|
|
|
|
SongInfo += char(3) + CSong->GetTranslitSubTitle();
|
|
|
|
|
SongInfo += char(4) + CSong->GetTranslitArtist();
|
2004-04-17 22:26:37 +00:00
|
|
|
|
|
|
|
|
for (j=4;j<SongInfo.length()+4;j++)
|
|
|
|
|
toSend[j] = SongInfo.c_str()[j-4];
|
2004-05-25 10:39:23 +00:00
|
|
|
toSend[0] = char(35);
|
|
|
|
|
toSend[1] = char(0);
|
|
|
|
|
toSend[2] = char(0);
|
|
|
|
|
toSend[3] = char(0);
|
2004-04-17 22:26:37 +00:00
|
|
|
|
2004-05-25 10:39:23 +00:00
|
|
|
NetPlayerClient->SendPack(toSend, SongInfo.length() + 4);
|
2004-04-17 22:26:37 +00:00
|
|
|
}
|
2004-05-25 10:39:23 +00:00
|
|
|
toSend[0] = char(36);
|
|
|
|
|
NetPlayerClient->SendPack(toSend, 4);
|
2004-04-17 22:26:37 +00:00
|
|
|
|
|
|
|
|
//Exit because this is ONLY for use with SMOnline
|
|
|
|
|
//If admins feel strongly, this can be exported
|
|
|
|
|
//to another command line, like "--exitfirst"
|
2004-05-25 10:39:23 +00:00
|
|
|
exit(0);
|
2004-04-17 22:26:37 +00:00
|
|
|
|
|
|
|
|
//NOTE TO ADMINS: I do not actually know the
|
|
|
|
|
//safe way to exit stepmania, if you can, either tell me
|
|
|
|
|
//or do it, please?
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-29 01:03:28 +00:00
|
|
|
|
|
|
|
|
void NetworkSyncManager::DisplayStartupStatus()
|
|
|
|
|
{
|
|
|
|
|
CString sMessage("");
|
2004-04-17 22:26:37 +00:00
|
|
|
|
2004-04-29 01:03:28 +00:00
|
|
|
switch (m_startupStatus)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
//Networking wasn't attepmpted
|
|
|
|
|
return;
|
|
|
|
|
case 1:
|
|
|
|
|
sMessage = "Connect to server successful.";
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
sMessage = "Connection failed.";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
SCREENMAN->SystemMessage(sMessage);
|
|
|
|
|
}
|
2004-04-17 22:26:37 +00:00
|
|
|
|
2004-05-24 13:59:05 +00:00
|
|
|
void NetworkSyncManager::Update(float fDeltaTime)
|
|
|
|
|
{
|
|
|
|
|
}
|
2004-06-15 02:21:16 +00:00
|
|
|
#endif
|
2004-04-17 22:26:37 +00:00
|
|
|
|
2004-06-08 01:24:17 +00:00
|
|
|
/*
|
|
|
|
|
* (c) 2003-2004 Charles Lohr, Joshua Allen
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
|
* distribute, and/or sell copies of the Software, and to permit persons to
|
|
|
|
|
* whom the Software is furnished to do so, provided that the above
|
|
|
|
|
* copyright notice(s) and this permission notice appear in all copies of
|
|
|
|
|
* the Software and that both the above copyright notice(s) and this
|
|
|
|
|
* permission notice appear in supporting documentation.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
|
|
|
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
|
|
|
|
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
|
|
|
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
|
|
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
|
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
*/
|