• Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

Code ServerPerks HELP!

relogin13

Grizzled Veteran
Dec 9, 2012
48
0
Hi people, I wanna to ask us, how can i make to save all people stats, like ServerPerksStat.ini? But i wanna make to save it to ftp, any ideas?

FTPDataConnection.uc
Class FTPDataConnection extends TcpLink;

var bool bUpload,bWasOpened;
var string Data;

delegate OnCompleted();

function PostBeginPlay()
{
LinkMode = MODE_Text;
}
event Opened()
{
BeginUpload();
}
event Closed()
{
OnCompleted();
Destroy();
}
event ReceivedText( string Text )
{
if( bUpload )
Log(Text,'FTPD');
else Data $= Text;
}
function BeginUpload()
{
if( bWasOpened )
GoToState('Uploading');
else bWasOpened = true;
}

state Uploading
{
function BeginState()
{
Tick(0.f);
}
function Tick( float Delta )
{
if( Data!="" )
{
SendText(Left(Data,250));
Data = Mid(Data,250);
}
else Close();
}
}
And
FTPTcpLink.uc
Class FTPTcpLink extends TcpLink;

var string TempFileName;
var array<ServerStStats> PendingLoaders;
var array<StatsObject> ToSave;
var ServerPerksMut Mut;
var IpAddr SiteAddress;
var FTPDataConnection DataConnection;
var transient float WelcomeTimer;
var array<string> TotalList;
var MessagingSpectator WebAdminController;
var byte RetryCounter;
var bool bConnectionBroken,bFullVerbose,bUploadAllStats,bTotalUpload,bFileInProgress,bLogAllCommands,bCheckedWeb,bPostUploadCheck,bIsAsciiMode;

function BeginEvent()
{
Mut.SaveAllStats = SaveAllStats;
Mut.RequestStats = RequestStats;
if( Mut.bDebugDatabase )
{
bLogAllCommands = true;
bFullVerbose = true;
}

LinkMode = MODE_Line;
ReceiveMode = RMODE_Event;
Resolve(Mut.RemoteDatabaseURL);
}
final function ReportError( int Code, string InEr )
{
if( !bConnectionBroken )
{
Level.Game.Broadcast(Self,Code$" FTP Error: "$InEr);
Log(Code$" FTP Error: "$InEr,Class.Name);
}
bConnectionBroken = true;
GoToState('ErrorState');
}
event Resolved( IpAddr Addr )
{
SiteAddress = Addr;
SiteAddress.Port = Mut.RemotePort;
GoToState('Idle');
}
event ResolveFailed()
{
ReportError(0,"Couldn't resolve address, aborting...");
}
event Closed()
{
ReportError(1,"Connection was closed by FTP server!");
}
final function DebugLog( string Str )
{
if( !bCheckedWeb )
{
bCheckedWeb = true;
foreach AllActors(class'MessagingSpectator',WebAdminController)
break;
}
if( WebAdminController!=None )
WebAdminController.ClientMessage(Str,'FTP');
Log(Str,'FTP');
}
event ReceivedLine( string Text )
{
if( bLogAllCommands )
DebugLog("ReceiveFTP "$GetStateName()$":"@Text);
ProcessResponse(int(Left(Text,3)),Mid(Text,4));
}
final function SendFTPLine( string Text )
{
if( bLogAllCommands )
DebugLog("SendFTP "$GetStateName()$":"@Text);
SendText(Text);
}

function SaveAllStats()
{
local int i;

if( bTotalUpload )
return;
ToSave = Mut.ActiveStats;
for( i=0; i<ToSave.Length; ++i )
{
if( !ToSave.bStatsChanged )
ToSave.Remove(i--,1);
}
if( ToSave.Length>0 )
bUploadAllStats = true;
}
function RequestStats( ServerStStats Other )
{
local int i;

if( bTotalUpload )
return;
for( i=0; i<PendingLoaders.Length; ++i )
{
if( PendingLoaders==None )
PendingLoaders.Remove(i--,1);
else if( PendingLoaders==Other )
return;
}
PendingLoaders[PendingLoaders.Length] = Other;
}
final function FullUpload()
{
TotalList = GetPerObjectNames("ServerPerksStat","StatsObject",9999999);
bTotalUpload = true;
bUploadAllStats = true;
bFullVerbose = true;
HasMoreStats();
SaveAllStats();
}
final function bool HasMoreStats()
{
local byte i;
local int j;

if( TotalList.Length==0 )
return false;
j = ToSave.Length;
for( i=0; i<Min(20,TotalList.Length); ++i )
{
ToSave.Length = j+1;
ToSave[j] = new(None,TotalList) Class'StatsObject';
++j;
}
TotalList.Remove(0,20);
return true;
}
final function CheckNextCommand()
{
while( PendingLoaders.Length>0 && PendingLoaders[0]==None )
PendingLoaders.Remove(0,1);

if( bUploadAllStats || (bTotalUpload && HasMoreStats()) )
GoToState('UploadStats','Begin');
else if( PendingLoaders.Length>0 )
GoToState('DownloadStats','Begin');
else
{
if( bFullVerbose )
Level.Game.Broadcast(Self,"FTP: All done!");
if( Mut.FTPKeepAliveSec>0 && !Level.Game.bGameEnded )
GoToState('KeepAlive');
else GoToState('EndConnection');
}
}
function ProcessResponse( int Code, string Line )
{
switch( Code )
{
case 220: // Welcome
if( WelcomeTimer<Level.TimeSeconds )
{
SendFTPLine("USER "$Mut.RemoteFTPUser);
WelcomeTimer = Level.TimeSeconds+0.2;
}
break;
case 331: // Password required
SendFTPLine("PASS "$Mut.RemotePassword);
break;
case 230: // User logged in.
if( Mut.RemoteFTPDir!="" )
SendFTPLine("CWD "$Mut.RemoteFTPDir);
else
{
SendFTPLine("TYPE A");
bIsAsciiMode = true;
}
break;
case 250: // CWD command successful.
SendFTPLine("TYPE A");
bIsAsciiMode = true;
break;
case 200: // Type set to A
CheckNextCommand();
break;
case 226: // File successfully transferred
case 150: // Opening ASCII mode data connection
break;
case 421: // No transfer timeout: closing control connection
if( bFullVerbose )
Level.Game.Broadcast(Self,"FTP: Connection timed out, reconnecting!");
GoToState('EndConnection');
break;
case 221: // Good-bye
Close();
break;
default:
if( bFullVerbose )
Level.Game.Broadcast(Self,"FTP: Unknown FTP code '"$Code$"': "$Line);
Log("Unknown FTP code '"$Code$"': "$Line,Class.Name);
}
}
function DataReceived();

final function bool OpenDataConnection( string S, bool bUpload )
{
local int i,j;
local IpAddr A;

A = SiteAddress;

// Get destination port
S = Mid(S,InStr(S,"(")+1);
for( i=0; i<4; ++i ) // Skip IP address
S = Mid(S,InStr(S,",")+1);
i = InStr(S,",");
A.Port = int(Left(S,i))*256 + int(Mid(S,i+1));

// Now attempt to bind port and open connection.
for( j=0; j<20; ++j )
{
if( DataConnection!=None )
DataConnection.Destroy();
DataConnection = Spawn(Class'FTPDataConnection',Self);
DataConnection.bUpload = bUpload;
DataConnection.BindPort(500+Rand(5000),true);
if( DataConnection.OpenNoSteam(A) )
return true;
}
DataConnection.Destroy();
DataConnection = None;
ReportError(2,"Couldn't bind port for upload data connection!");
return false;
}

function Timer()
{
ReportError(3,"FTP connection timed out!");
}

state Idle
{
Ignores Timer;

final function StartConnection()
{
local int i;

for( i=0; i<40; ++i )
{
BindPort(500+Rand(5000),true);
if( OpenNoSteam(SiteAddress) )
{
GoToState('InitConnection');
return;
}
}
ReportError(4,"Port couldn't be bound or connection failed to open!");
}
function SaveAllStats()
{
Global.SaveAllStats();
if( bUploadAllStats )
StartConnection();
}
function RequestStats( ServerStStats Other )
{
Global.RequestStats(Other);
StartConnection();
}
Begin:
Sleep(0.1f);
if( bUploadAllStats || PendingLoaders.Length>0 )
StartConnection();
}
state InitConnection
{
function BeginState()
{
SetTimer(10,false);
}
event Closed()
{
ReportError(5,"Connection was closed by FTP server!");
}
Begin:
Sleep(5.f);
SendFTPLine("USER "$Mut.RemoteFTPUser);
}
state ConnectionBase
{
event Closed()
{
GoToState('Idle');
}
Begin:
while( true )
{
if( bUploadAllStats && Level.bLevelChange ) // Delay mapchange until all stats are uploaded.
Level.NextSwitchCountdown = FMax(Level.NextSwitchCountdown,1.f);
Sleep(0.5);
}
}
state EndConnection extends ConnectionBase
{
function BeginState()
{
SendFTPLine("QUIT");
SetTimer(4,false);
}
}
state KeepAlive extends ConnectionBase
{
Ignores Timer;

function SaveAllStats()
{
Global.SaveAllStats();
if( bUploadAllStats )
StartConnection();
}
function RequestStats( ServerStStats Other )
{
Global.RequestStats(Other);
StartConnection();
}
final function StartConnection()
{
CheckNextCommand();
}
Begin:
while( true )
{
if( bUploadAllStats || PendingLoaders.Length>0 )
StartConnection();
Sleep(Mut.FTPKeepAliveSec);
SendFTPLine("NOOP");
}
}
state UploadStats extends ConnectionBase
{
function BeginState()
{
bUploadAllStats = false;
SetTimer(10,false);
}
function SaveAllStats();

final function InitDataConnection( string S )
{
if( bFullVerbose )
Level.Game.Broadcast(Self,"FTP: Upload stats for "$ToSave[0].PlayerName$" ("$(ToSave.Length-1+TotalList.Length)$" remains)");
if( OpenDataConnection(S,true) )
{
DataConnection.Data = ToSave[0].GetSaveData();
TempFileName = ToSave[0].Name$"ServerPerksStat.ini";
SendFTPLine("STOR "$TempFileName);
bFileInProgress = true;
}
}
final function NextPackage()
{
RetryCounter = 0;
ToSave[0].bStatsChanged = false;
ToSave.Remove(0,1);
if( ToSave.Length==0 )
CheckNextCommand();
else if( !bIsAsciiMode )
{
bIsAsciiMode = true;
SendFTPLine("TYPE A");
}
else SendFTPLine("PASV");
}
function ProcessResponse( int Code, string Line )
{
switch( Code )
{
case 200: // Type set to A/I
if( bPostUploadCheck )
{
SetTimer(5,false);
SendFTPLine("SIZE "$TempFileName);
}
else SendFTPLine("PASV");
break;
case 227: // Entering passive mode
if( !bFileInProgress )
InitDataConnection(Line);
break;
case 150: // Opening ASCII mode data connection for file
SetTimer(60,false);
if( DataConnection!=None )
DataConnection.BeginUpload();
break;
case 226: // File transfer completed.
if( bFileInProgress )
{
SetTimer(5,false);
bFileInProgress = false;
bPostUploadCheck = true;
SendFTPLine("TYPE I");
bIsAsciiMode = false;
}
break;
case 213: // File size response.
if( bPostUploadCheck )
{
SetTimer(5,false);
if( int(Line)<=5 )
{
bPostUploadCheck = false;
if( ++RetryCounter>=5 )
NextPackage();
else
{
if( bFullVerbose )
Level.Game.Broadcast(Self,"213 FTP Error: Stats upload failed for "$ToSave[0].PlayerName$" retrying...");
SendFTPLine("PASV");
}
}
else SendFTPLine("RNFR "$TempFileName);
}
break;
case 550: // Sorry, but that file doesn't exist
if( bPostUploadCheck )
{
SetTimer(5,false);
bPostUploadCheck = false;
if( ++RetryCounter>=5 )
NextPackage();
else
{
if( bFullVerbose )
Level.Game.Broadcast(Self,"550 FTP Error: Stats upload failed for "$ToSave[0].PlayerName$" retrying...");
SendFTPLine("PASV");
}
}
break;
default:
Global.ProcessResponse(Code,Line);
}
}
Begin:
if( !bIsAsciiMode )
{
SendFTPLine("TYPE A");
bIsAsciiMode = true;
}
else SendFTPLine("PASV");
while( true )
{
if( Level.bLevelChange ) // Delay mapchange until all stats are uploaded.
{
bFullVerbose = true;
Level.NextSwitchCountdown = FMax(Level.NextSwitchCountdown,1.f);
}
Sleep(0.5);
}
}
state DownloadStats extends ConnectionBase
{
function BeginState()
{
SetTimer(10,false);
}
final function InitDataConnection( string S )
{
while( PendingLoaders.Length>0 && PendingLoaders[0]==None )
PendingLoaders.Remove(0,1);
if( PendingLoaders.Length==0 )
{
CheckNextCommand();
return;
}

if( bFullVerbose )
Level.Game.Broadcast(Self,"FTP: Download stats for "$PendingLoaders[0].MyStatsObject.PlayerName$" ("$(PendingLoaders.Length-1)$" remains)");

if( OpenDataConnection(S,false) )
{
DataConnection.OnCompleted = DataReceived;
SendFTPLine("RETR "$PendingLoaders[0].MyStatsObject.Name$"ServerPerksStat.ini");
bFileInProgress = true;
}
}
function DataReceived()
{
bFileInProgress = false;
if( PendingLoaders[0]!=None )
{
if( DataConnection!=None )
PendingLoaders[0].GetData(DataConnection.Data);
else PendingLoaders[0].GetData("");
}
PendingLoaders.Remove(0,1);
while( PendingLoaders.Length>0 && PendingLoaders[0]==None )
PendingLoaders.Remove(0,1);

if( bUploadAllStats ) // Saving has higher priority.
GoToState('UploadStats');
else if( PendingLoaders.Length>0 )
SendFTPLine("PASV");
else CheckNextCommand();
}
function ProcessResponse( int Code, string Line )
{
switch( Code )
{
case 200: // Type set to A
SendFTPLine("PASV");
break;
case 227: // Entering passive mode
if( !bFileInProgress )
InitDataConnection(Line);
break;
case 150: // Opening ASCII mode data connection for file
SetTimer(60,false);
break;
case 550: // No such file or directory
SetTimer(10,false);
if( bFileInProgress )
{
if( DataConnection!=None )
DataConnection.Destroy();
DataReceived();
}
break;
default:
Global.ProcessResponse(Code,Line);
}
}
Begin:
if( !bIsAsciiMode )
{
bIsAsciiMode = true;
SendFTPLine("TYPE A");
}
else SendFTPLine("PASV");
while( true )
{
if( bUploadAllStats && Level.bLevelChange ) // Delay mapchange until all stats are uploaded.
{
bFullVerbose = true;
Level.NextSwitchCountdown = FMax(Level.NextSwitchCountdown,1.f);
}
Sleep(0.5);
}
}
state ErrorState
{
Ignores SaveAllStats,RequestStats;
Begin:
Sleep(1.f);
Mut.RespawnNetworkLink();
}

defaultproperties
{
}


I Know on these files are functions that uploads to ftp every player id in new txt file, i wanna to make that save to one file.