AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   Code needed for String and Type conversions (https://forums.alliedmods.net/showthread.php?t=238013)

souvikdas95 04-02-2014 11:51

Code needed for String and Type conversions
 
Quote:

Originally Posted by Bugsy (Post 1325056)
Well I coded reading and writing to csstats.dat successfully in Pawn but all changes made by my code are lost at map-change\restart since the csstats.dat file is open and being manipulated by csx module while the server is running. Someone will need to code this into the dll.

Here it is if anyone needs it for anything.
PHP Code:

#include <amxmodx>
#include <amxmisc>
#include <csx>

/*  -- csstats.dat file structure --
    * int16 - RANK_VERSION
    * uint16 - Bytes in first string (if 0, no entries)
          o sz - Name (read N bytes, where N is previous uint16)
          o uint16 - Bytes of next string
          o sz - Steam ID (read N bytes, where N is previous uint16)
          o uint32 - Team kills
          o uint32 - Damage
          o uint32 - Deaths
          o int32 - Kills
          o uint32 - Shots
          o uint32 - Hits
          o uint32 - Headshots
          o uint32 - Defusions
          o uint32 - Defusal Attempts
          o uint32 - Plants
          o uint32 - Explosions
          o uint32[9] - Body Hits (array of ints, one for each body hit area)
          o uint16 - If zero, end of file. Otherwise, loop back up and read the next name for this many bytes. 
*/

const RANK_VERSION 11;

//Array sizes for storing data in csstats.dat
const STATS_SIZE 11;
const 
BODYHITS_SIZE 9;

//Array sizes CSX functions use for reading data with natives
const CSX_STATS_SIZE 8;
const 
CSX_BODYHITS_SIZE 8;

enum _:Stats
{
    
TeamKills,  //3
    
Damage,     //6
    
Deaths,     //1
    
Kills,      //0
    
Shots,      //4
    
Hits,       //5
    
Headshots//2
    
Defusions//7
    
DefusalAttempts,
    
Plants,
    
Explosions
}

enum _:BodyHits
{
    
Generic,
    
Head,
    
Chest,
    
Stomach,
    
LeftArm,
    
RightArm,
    
LeftLeg,
    
RightLeg,
    Empty
}

new 
StatsTable[] = 
{
    
Kills,
    
Deaths,
    
Headshots,
    
TeamKills,
    
Shots,
    
Hits,
    
Damage,
    
Defusions
};

public 
plugin_init() 
{
    
register_clcmd"say hi" "Test" );
}

public 
Testid )
{
    new 
iStats] , iBHits];
    
    
//Get position in stats and stats data from csstats.dat
    
new iRankPos get_user_statsid iStats iBHits );
    
    
server_print"STATS BEFORE WRITE" );
    
    
//Read existing stats
    
ReadStats();
    
    
//Modify values to check if they change
    
iStats] = 1101;
    
iStats] = 1102;
    
iStats] = 1103;
    
iStats] = 1104;
    
iStats] = 1105;
    
iStats] = 1106;
    
iStats] = 1107;
    
iStats] = 1108;
    
    
//Write new values
    
WriteStatsiRankPos iStats iBHits );
    
    
server_print"STATS AFTER WRITE" );
    
    
//Read to see if changed after writing
    
ReadStats();
}
    
public 
ReadStats()
{
    new 
szFile64 ] , iFile;
    new 
iData10 ];
    new 
szString35 ] , iStringLen;
    new 
iStatsStats ] , iBHitsBodyHits ];
    
    
//Format the file name
    
copyszFileget_datadirszFile charsmaxszFile ) ) ] , charsmaxszFile ) , "/csstats.dat" );
    
    
//Open file for binary read
    
iFile fopenszFile "rb" );

    
//Read rank version
    
fread_rawiFile iData BLOCK_SHORT );
    
    if ( 
iData] != RANK_VERSION )
        
set_fail_state"Rank version does not match" );
    
    
//Read first name len (if 0, there are no player in stats file)
    
fread_rawiFile iData BLOCK_SHORT );
    
iStringLen iData] & 0xFFFF;

    while ( 
iStringLen )
    {        
        
//Read name
        
fread_rawiFile iData iStringLen BLOCK_CHAR );
        
ReadStringszString iStringLen charsmaxszString ) , iData );
        
server_print"Name: %s" szString );
        
        
//Read steamid len
        
fread_rawiFile iData BLOCK_SHORT );
        
iStringLen iData] & 0xFFFF;
        
        
//Read steamid
        
fread_rawiFile iData iStringLen BLOCK_CHAR );
        
ReadStringszString iStringLen charsmaxszString ) , iData );
        
server_print"SteamID: %s" szString );
        
        
//Read stats data
        
fread_rawiFile iStats STATS_SIZE BLOCK_INT );
        
server_print"%d %d %d %d %d %d %d %d %d %d %d" iStatsDamage ] ,
                                
iStatsKills ] ,
                                
iStatsDeaths ] ,
                                
iStatsTeamKills ] ,
                                
iStatsShots ] ,
                                
iStatsHits ] ,
                                
iStatsHeadshots ] ,
                                
iStatsPlants ] ,
                                
iStatsExplosions ] ,
                                
iStatsDefusions ] ,
                                
iStatsDefusalAttempts ] );
        
        
//Read body-hit data
        
fread_rawiFile iBHits BODYHITS_SIZE BLOCK_INT );
        
server_print"%d %d %d %d %d %d %d %d %d" iBHitsGeneric ] ,
                                
iBHitsHead ] ,
                                
iBHitsChest ] ,
                                
iBHitsStomach ] ,
                                
iBHitsLeftArm ] ,
                                
iBHitsRightArm ] ,
                                
iBHitsLeftLeg ] ,
                                
iBHitsRightLeg ] ,
                                
iBHits] );
        
        
//Read next players name len (if 0, end of stats)
        
fread_rawiFile iData BLOCK_SHORT );
        
iStringLen iData] & 0xFFFF;
    }
    
    
fcloseiFile );    
}

public 
WriteStatsiEntry iStatsCSX_STATS_SIZE ] , iBHitsCSX_BODYHITS_SIZE ] )
{
    new 
szFile64 ] , iFile;
    new 
iData10 ];
    new 
iStringLen;
    new 
iCurrentEntry;
    
    
copyszFileget_datadirszFile charsmaxszFile ) ) ] , charsmaxszFile ) , "/csstats.dat" );
    
    if ( !( 
iFile fopenszFile "rb+" ) ) )
        
set_fail_state"Error at file open" );
        
    
fread_rawiFile iData BLOCK_SHORT );
    
    if ( 
iData] != RANK_VERSION )
        
set_fail_state"Rank version does not match" );
    
    
fread_rawiFile iData BLOCK_SHORT );
        
    
iStringLen iData] & 0xFFFF;

    while ( 
iStringLen && ( ++iCurrentEntry <= iEntry ) )
    {
        
//Seek past the name data
        
fseekiFile iStringLen SEEK_CUR );
        
        
//Read steam-id len
        
fread_rawiFile iData BLOCK_SHORT );
        
iStringLen iData] & 0xFFFF;

        
//Seek past steam-id data
        
fseekiFile iStringLen SEEK_CUR );
        
        
//If current entry is the one we want to modify
        
if ( iCurrentEntry == iEntry )
        {
            
//The order of stats saved to csstats.dat and the order used
            //by csx are different, this puts them in correct order.
            
FixStatsOrderiStats );

            
//Write stats array
            
fwrite_rawiFile iStats CSX_STATS_SIZE BLOCK_INT )
            
//Only 8 of 11 ints are written so we seek past 3
            
fseekiFile , ( STATS_SIZE CSX_STATS_SIZE ) * BLOCK_INT SEEK_CUR );
            
            
//Write body-hit data
            
fwrite_rawiFile iBHits CSX_BODYHITS_SIZE BLOCK_INT );
            
//Only 8 of 9 ints are written so we seek past 1
            
fseekiFile , ( BODYHITS_SIZE CSX_BODYHITS_SIZE ) * BLOCK_INT SEEK_CUR );
        }
        else
        {
            
//This is not the entry that we want to modify so we skip past
            //the stats and bodyhit data.
            
fseekiFile , ( ( STATS_SIZE BODYHITS_SIZE ) * BLOCK_INT ) , SEEK_CUR );
        }
        
        
fread_rawiFile iData BLOCK_SHORT );    
        
iStringLen iData] & 0xFFFF;
    }
    
    
fcloseiFile );    
}

FixStatsOrderiStats] )
{
    new 
iTmpStats];
    
    
iTmpStats iStats;

    for ( new 
i++ )
        
iStats] = iTmpStatsStatsTable] ]; 
}

ReadStringszDestString[] , iLen iMaxLen SourceData[] )
{
    new 
iStrPos = -1;
    new 
iRawPos 0;
    
    while ( ( ++
iStrPos iLen ) && ( iStrPos iMaxLen ) && ( iRawPos 10 ) )
    {
        
szDestStringiStrPos ] = ( SourceDataiRawPos ] >> ( ( iStrPos ) * ) ) & 0xFF;
    
        if ( 
iStrPos && ( ( iStrPos ) == ) )
            
iRawPos++
    }
    
    
szDestStringiStrPos ] = EOS;


Code:

STATS BEFORE WRITE

Name: bugsy
SteamID: STEAM_0:0:12345
121 2 43 0 8274 2 0 7 7 2 2
0 0 0 2 0 0 0 0 0

STATS AFTER WRITE

Name: bugsy
SteamID: STEAM_0:0:12345
1103 1101 1107 1104 1105 1106 1102 7 7 1108 2
0 0 0 2 0 0 0 0 0


1. I require conversion of int back to shortint
2. I require WriteString() doing opposite work to that of ReadString()

Shooting King 04-04-2014 07:45

Re: Code needed for String and Type conversions
 
This thread should be in Module Coding section because Pawn does not have ints and shorts.
Quote:

Originally Posted by souvikdas95 (Post 2119277)
1. I require conversion of int back to shortint

sizeof int > sizeof shortint
.'. MaxValue of int > MaxValue of short
.'. You cannot convert int to shortint properly. You CAN convert int to shortint if value of int is in the Range of shortint.

Quote:

Originally Posted by souvikdas95 (Post 2119277)
2. I require WriteString() doing opposite work to that of ReadString()

XY Problem

Black Rose 04-04-2014 16:03

Re: Code needed for String and Type conversions
 
That ReadString() seems broken or I'm misunderstanding it.

EDIT: This is from nvault_util.inc:
Code:
stock ReadString( szDestString[] , iMaxLen , const SourceData[] , iSourceSize ) {     /*    Memory layout     szDest[ 0 ] = Source{ 3 }     szDest[ 1 ] = Source{ 2 }     szDest[ 2 ] = Source{ 1 }     szDest[ 3 ] = Source{ 0 }     szDest[ 4 ] = Source{ 7 }     szDest[ 5 ] = Source{ 6 }     szDest[ 6 ] = Source{ 5 }     szDest[ 7 ] = Source{ 4 }     szDest[ 8 ] = Source{ 11 }     */             new iDestPos = -1;     new iBytePos = 4;     new iOffset = 1;     new iSourceMax = ( iSourceSize * 4 );         while ( ( ++iDestPos < iMaxLen ) && ( iBytePos < iSourceMax ) )     {         szDestString[ iDestPos ] = SourceData{ iBytePos - iOffset++ };         if ( iDestPos && ( ( iDestPos % 4 ) == 3 ) )         {             iBytePos += 4;             iOffset = 1;         }     }         szDestString[ iDestPos ] = EOS; }

EDIT2: I made these now:
Never seen {} being used to write bytes before, only to define arrays. I had no idea you could do that.
Code:
#include <amxmodx> public plugin_init() {     register_plugin("Test Plugin 4", "", "[ --{-@ ]");         new Original[] = "Hello World";         server_print("^nOriginal:");     server_print("%s", Original);         new String1[4];     WriteString(String1, charsmax(String1), Original);         server_print("^nWriteString():");     for ( new i ; i < charsmax(String1) && String1[i] ; i++ )         server_print("%d: 0x%08x (%c%c%c%c)", i, String1[i], String1{i * 4} == 0 ? ' ' : String1{i * 4}, String1{i * 4 + 1} == 0 ? ' ' : String1{i * 4 + 1}, String1{i * 4 + 2} == 0 ? ' ' : String1{i * 4 + 2}, String1{i * 4 + 3});         new String2[12];     ReadString(String2, charsmax(String2), String1);         server_print("^nReadString():");     server_print("%s", String2); } stock ReadString(Output[], maxlen, const Input[]) {         new i, len = strlen(Input) * 4;         for ( ; i < len && i < maxlen ; i++ )         Output[i] = Input{i - i % 4 + ( 3 - i % 4 )};         Output[i] = 0; } stock WriteString(Output[], maxlen, const Input[]) {         new len, len2, i;     len = len2 = strlen(Input);     if ( len % 4 )         len2 += 4 - len % 4         for ( ; i < maxlen * 4 && i < len2 ; i++ )             Output{i - i % 4 + ( 3 - i % 4 )} = i < len ? Input[i] : 0;         Output[i / 4] = 0; }

Code:

Original:
Hello World

WriteString():
0: 0x6c6c6548 (lleH)
1: 0x6f57206f (oW o)
2: 0x00646c72 ( dlr)

ReadString():
Hello World


souvikdas95 04-05-2014 12:23

Re: Code needed for String and Type conversions
 
@Shooting King - True but assume that it's in range. CSX does that all the time during file save.
http://stackoverflow.com/questions/2...wise-operators
I liked the last given answer.

@Black Rose - Great! I will try and tell you if it works from my side as well :)


All times are GMT -4. The time now is 05:57.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.