Thread: [Request] Save scores between maps changes

Results 1 to 6 of 6
  1. #1
    ℍ𝕖𝕝𝕡 Cadaver's Avatar
    Join Date
    Mar 2016
    Location
    Argentina
    Posts
    89

    [Request] Save scores between maps changes

    Well, the title explain what I'm searching for, could be nice this to use whit the buy menu, thanks.



  2. #2
    Giegue
    Join Date
    Oct 2013
    Location
    Argentina
    Posts
    92

    Re: [Request] Save scores between maps changes

    All maps (plugin)? Or only for specific maps (map script)?
    What's a signature?

  3. #3
    ℍ𝕖𝕝𝕡 Cadaver's Avatar
    Join Date
    Mar 2016
    Location
    Argentina
    Posts
    89

    Re: [Request] Save scores between maps changes

    A plugin, and if it's possible a way to toggle it, thanks



  4. #4
    Giegue
    Join Date
    Oct 2013
    Location
    Argentina
    Posts
    92

    Re: [Request] Save scores between maps changes

    I have to warn you: Persistent file access is not yet granted (SQL for a tiny thing like this is overkill). I'm forced to save on a temporary directory, which means the player's score might be wiped out on a server crash.

    Try this:

    Code:
    // Path where the player's data will be saved
    const string datapath = "scripts/plugins/temp/";
    
    // Current score of the player
    array< float > flPlayerScore( 33 );
    
    // Load protecting flag to prevent data being loaded/saved when it shouldn't
    array< bool > bLoadData( 33 );
    
    // Last score of the player
    array< float > flLastFrags( 33 );
    
    // Whenever data saving is active or not
    CCVar@ pCvar_Active;
    
    void PluginInit()
    {
       // Register script information
       g_Module.ScriptInfo.SetAuthor( "Julian \"Giegue\" Rodriguez" );
       g_Module.ScriptInfo.SetContactInfo( "www.steamcommunity.com/id/ngiegue" );
       
       // Register neccesary hooks
       g_Hooks.RegisterHook( Hooks::Player::ClientPutInServer, @ClientPutInServer );
       g_Hooks.RegisterHook( Hooks::Player::ClientDisconnect, @ClientDisconnect );
       
       // Register our CVar
       //
       // Default is 1 (Enabled)
       //
       // 0 = Disabled
       // 1 = Enabled
       // 2 = Admins (and Owners) Only
       // 3 = Owners Only
       //
       @pCvar_Active = CCVar( "ss_active", 1, "Save player's score?", ConCommandFlag::AdminOnly );
       
       // Save player's data every 1.0 seconds, fell free to change the interval
       g_Scheduler.SetInterval( "ScoreTask", 1.0, g_Scheduler.REPEAT_INFINITE_TIMES );
    }
    
    void MapInit()
    {
       // Reset variables after mapchange
       for ( int i = 0; i < 33; i++ )
       {
          flPlayerScore[ i ] = 0.0;
          flLastFrags[ i ] = 0.0;
          bLoadData[ i ] = false;
       }
    }
    
    // Prepare data on client connect
    HookReturnCode ClientPutInServer( CBasePlayer@ pPlayer )
    {
       // Get CVar value
       int iCvar = pCvar_Active.GetInt();
       
       // Invalid values, pretend it's disabled
       if ( iCvar < 0 || iCvar > 3 )
          iCvar = 0;
       
       // Data saving/loading is disabled
       if ( iCvar == 0 )
          return HOOK_CONTINUE;
    	
       // Get the player's admin level
       AdminLevel_t aLevel = g_PlayerFuncs.AdminLevel( pPlayer );
       
       // Not an admin and data saving/loading is enabled for admins/owners only?
       if ( aLevel == ADMIN_NO && iCvar >= 2 )
          return HOOK_CONTINUE;
       
       // Player is Admin/Owner and data saving/loading is enabled for admins/owners only?
       if ( aLevel != ADMIN_YES && iCvar >= 2 || aLevel != ADMIN_OWNER && iCvar >= 2 )
          return HOOK_CONTINUE;
       if ( aLevel != ADMIN_OWNER && iCvar == 3 )
          return HOOK_CONTINUE;
       
       // Allowed player, set initial values
       int index = pPlayer.entindex();
       
       flLastFrags[ index ] = 0.0;
       bLoadData[ index ] = false;
       
       // Load the data!
       LoadScore( index );
       
       return HOOK_CONTINUE;
    }
    
    // Clear data on disconnect
    HookReturnCode ClientDisconnect( CBasePlayer@ pPlayer )
    {
       // Get CVar value
       int iCvar = pCvar_Active.GetInt();
       
       // Invalid values, pretend it's disabled
       if ( iCvar < 0 || iCvar > 3 )
          iCvar = 0;
       
       // Data saving/loading is disabled
       if ( iCvar == 0 )
          return HOOK_CONTINUE;
       
       // Get the player's admin level
       AdminLevel_t aLevel = g_PlayerFuncs.AdminLevel( pPlayer );
       
       // Not an admin and data saving/loading is enabled for admins/owners only?
       if ( aLevel == ADMIN_NO && iCvar >= 2 )
          return HOOK_CONTINUE;
       
       // Player is Admin/Owner and data saving/loading is enabled for admins/owners only?
       if ( aLevel != ADMIN_YES && iCvar >= 2 || aLevel != ADMIN_OWNER && iCvar >= 2 )
          return HOOK_CONTINUE;
       if ( aLevel != ADMIN_OWNER && iCvar == 3 )
          return HOOK_CONTINUE;
       
       // Allowed player, save player data
       int index = pPlayer.entindex();
       SaveScore( index );
       
       // Clear variables
       flLastFrags[ index ] = 0.0;
       bLoadData[ index ] = false;
       
       return HOOK_CONTINUE;
    }
    
    // Score handler
    void ScoreTask()
    {
       // Loop through all indexes
       for ( int i = 1; i <= g_Engine.maxClients; i++ )
       {
          // Get player
          CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex( i );
          
          // Check if player is valid (and connected)
          if ( pPlayer !is null && pPlayer.IsConnected() )
          {
             // Prevent negative scores
             if ( pPlayer.pev.frags < 0 )
                pPlayer.pev.frags = flPlayerScore[ i ] = flLastFrags[ i ] = 0.0;
             
             // Add frags
             flPlayerScore[ i ] = flPlayerScore[ i ] + pPlayer.pev.frags - flLastFrags[ i ];
             
             // Save Data
             SaveScore( i );
             
             // Save last earned frags to prevent looping
             flLastFrags[ i ] = pPlayer.pev.frags;
          }
       }
    }
    
    // Save player's data
    void SaveScore( const int& in index )
    {
       // Get CVar value
       int iCvar = pCvar_Active.GetInt();
       
       // Invalid values, pretend it's disabled
       if ( iCvar < 0 || iCvar > 3 )
          iCvar = 0;
       
       // Data saving is disabled
       if ( iCvar == 0 )
          return;
       
       CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex( index );
       
       // Can we save data?
       if ( bLoadData[ index ] )
       {
          // Format the string using the directory path, followed by the player's SteamID
          // ( svencoop/scripts/plugins/temp/SS_STEAM_0:1:23456789.data )
          string fullpath = "" + datapath + "SS_" + g_EngineFuncs.GetPlayerAuthId( pPlayer.edict() ) + ".data";
          
          // File names cannot contain the ":" character, replace them with underscores
          fullpath.Replace( ':', '_' );
          
          // Now, open up for writing
          File@ thefile = g_FileSystem.OpenFile( fullpath, OpenFile::WRITE );
          
          // File is open?
          if ( thefile !is null && thefile.IsOpen() )
          {
             // Write away!
             string stuff;
             
             stuff += "" + flPlayerScore[ index ] + "\n";
             
             thefile.Write( stuff );
             thefile.Close();
          }
       }
    }
    
    // Load player's data
    void LoadScore( const int& in index )
    {
       CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex( index );
       
       // Format the string using the directory path, followed by the player's SteamID
       // ( svencoop/scripts/plugins/temp/SS_STEAM_0:1:23456789.data )
       string fullpath = "" + datapath + "SS_" + g_EngineFuncs.GetPlayerAuthId( pPlayer.edict() ) + ".data";
       
       // File names cannot contain the ":" character, replace them with underscores
       fullpath.Replace( ':', '_' );
       
       // Read the file
       File@ thefile = g_FileSystem.OpenFile( fullpath, OpenFile::READ );
       
       // File is open?
       if ( thefile !is null && thefile.IsOpen() )
       {
          // Get the player's score!
          string line;
          
          thefile.ReadLine( line );
          
          line.Trim();
          
          flPlayerScore[ index ] = atof( line );
          
          // Now, update the player with the new frags so they became usable
          pPlayer.pev.frags = flPlayerScore[ index ];
          flLastFrags[ index ] = flPlayerScore[ index ];
          
          thefile.Close();
       }
       
       // Set our flag
       bLoadData[ index ] = true;
    }
    Or just download the script by clicking this little text.

    Next, install it on svencoop_addon/scripts/plugins

    On your base svencoop folder, edit default_plugins.txt and add this:

    Code:
    	"plugin"
    	{
    		"name" "Score Saver"
    		"script" "ScoreSave"
    	}
    To the end of the file. Save and you are good to go. Reload plugins if needed with as_reloadplugins on the server's console.

    As for toggling the saving on and off. I've added a CVar named ss_active. To set it, send command as_command .ss_active [value] on the server's console; Where [value] can be:

    0 = Disabled.
    1 = Enabled.
    2 = Enabled for Admins/Owners only.
    3 = Enabled for Owners only.

    Did a quick test and it apparently works, but please. Inform me if anything fails.
    Last edited by Julcoool; 09-10-2016 at 10:19 AM. Reason: Script update
    What's a signature?

  5. #5
    ℍ𝕖𝕝𝕡 Cadaver's Avatar
    Join Date
    Mar 2016
    Location
    Argentina
    Posts
    89

    Re: [Request] Save scores between maps changes

    Hey thanks a lot for this, I'll try it and tell you. Thanks

    *I try it and works perfect!,
    I have a suggest, it's possible reset the score of people who have negative values? (-1, etc).
    Last edited by Cadaver; 09-10-2016 at 05:09 AM.



  6. #6
    Giegue
    Join Date
    Oct 2013
    Location
    Argentina
    Posts
    92

    Re: [Request] Save scores between maps changes

    Sure thing.

    Go to void ScoreTask() located in line 130. And below Check if player is valid ( if ( pPlayer !is null && pPlayer.IsConnected() ) )
    add this piece of code:

    Code:
    // Prevent negative scores
    if ( pPlayer.pev.frags < 0 )
       pPlayer.pev.frags = flPlayerScore[ i ] = flLastFrags[ i ] = 0.0;
    This will prevent negative scores by resetting it back to 0.

    If you did it right, it should look like this:

    Code:
    // Score handler
    void ScoreTask()
    {
       // Loop through all indexes
       for ( int i = 1; i <= g_Engine.maxClients; i++ )
       {
          // Get player
          CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex( i );
          
          // Check if player is valid (and connected)
          if ( pPlayer !is null && pPlayer.IsConnected() )
          {
             // Prevent negative scores
             if ( pPlayer.pev.frags < 0 )
                pPlayer.pev.frags = flPlayerScore[ i ] = flLastFrags[ i ] = 0.0;
             
             // Add frags
             flPlayerScore[ i ] = flPlayerScore[ i ] + pPlayer.pev.frags - flLastFrags[ i ];
             
             // Save Data
             SaveScore( i );
             
             // Save last earned frags to prevent looping
             flLastFrags[ i ] = pPlayer.pev.frags;
          }
       }
    }
    Or just re-download the script I've just updated on my previous post.
    What's a signature?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •