Skip to forum content

You are not logged in. Please login or register.


forums.pvpgn.pro → [RU] The Source Code → Помогите поправить.

Pages 1

You must login or register to post a reply

RSS topic feed

Posts: 2

1

Topic: Помогите поправить.

Суть проблемы:
На гхост боте стата ДОТЫ считается с помощью приложения update_dota_elo, исходники этого приложения вшиты в сервер PVPGN. То есть update_dota_elo считает стату и отправляет её в базу данных не GHOSTBOT а PVPGN. Проблема в том, что когда новый игрок зашедший на сервер играет игру и после игры, когда подсчитывается его стата, то всё работает без проблем. То есть ему выдаются птс. К примеру было у него 1000 птс, а стало 1100. А когда этот же игрок играет вторую игру, птс может не засчитать после окончания этой игры, так же и третью, четвертую... В чём суть проблемы я толком не понял.
Я пробовал удалять данные о птс очках своих игроков и заново запускать подсчёт статистики для всех игр, после повторного подсчёте некоторые игры, которые раннее не были засчитаны - засчитались!
Ошибка при засчёте других игр в основном "gameid [chislo] has more than 10 players, ignoring" хотя игроков в игре всегда 10.
Я думаю так, dota_elo записывает без проблем игры, если в игре игроки, не имеющие в базе данных не одной игры, то есть новые игроки, а если игрок имеет хотя бы 1 игру, то dota_elo не засчитывает этого игрока.
[img]geekpic.net/dt-2R7JX2.jpg[/img]
gameid 25 - игра не засчитана. Тут всё верно, в игре нет выигравшей команды.
gameid 26 - тут тоже самое.
gameid 27 - игра засчитана.
А если поднять чуть выше, то тут:
[img]geekpic.net/dt-63LLA9.jpg[/img]
gameid 23 - найдены новые игроки, как и в gameid 27, но птс не засчитывает.
В общем такая передряга. Может в коде что-нибудь поправить?

bool elothreadstatus = true;

        extern unsigned long __stdcall EloThread( void * arg1 )
        {
            string CFGFile = ".\\update_dota_elo.cfg";
            CIniReader  CFG( CFGFile.c_str( ) );
            string Server = CFG.ReadString( "DotaElo" , "db_mysql_server" , "127.0.0.1" );
            string Database = CFG.ReadString( "DotaElo" , "db_mysql_database" , "ghost" );
            string User = CFG.ReadString( "DotaElo" , "db_mysql_user" , "root" );
            string Password = CFG.ReadString( "DotaElo" , "db_mysql_password" , "" );
            int Port = CFG.ReadInteger( "DotaElo" , "db_mysql_port" , 0 );


            eventlog( eventlog_level_debug , __FUNCTION__ , "-> %s" ,"connecting to database server" );
            MYSQL *Connection = NULL;

            if ( !( Connection = mysql_init( NULL ) ) )
            {
                eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ));
                elothread = NULL;
                return 0;
            }

            my_bool Reconnect = true;
            mysql_options( Connection , MYSQL_OPT_RECONNECT , &Reconnect );



            if ( !( mysql_real_connect( Connection , Server.c_str( ) , User.c_str( ) , Password.c_str( ) , Database.c_str( ) , Port , NULL , 0 ) ) )
            {
                eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                elothread = NULL;
                return 0;
            }

            while ( true )
            {
                if ( !elothreadstatus )
                {
                    mysql_close( Connection );

                    elothread = NULL;
                    elothreadstatus = true;
                    ExitThread( 0 );
                    return 0;
                }
                Sleep( 5000 );

                cout << "connected" << endl;
                cout << "beginning transaction" << endl;

                string QBegin = "BEGIN";

                if ( mysql_real_query( Connection , QBegin.c_str( ) , QBegin.size( ) ) != 0 )
                {
                    eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                    elothread = NULL;
                    Sleep( 1000 );
                    return 0;
                }

                cout << "creating tables" << endl;

                string QCreate1 = "CREATE TABLE IF NOT EXISTS dota_elo_scores ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(15) NOT NULL, server VARCHAR(100) NOT NULL, score REAL NOT NULL, streak INT NOT NULL , leaves INT UNSIGNED NOT NULL )";
                string QCreate2 = "CREATE TABLE IF NOT EXISTS dota_elo_games_scored ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, gameid INT NOT NULL )";

                if ( mysql_real_query( Connection , QCreate1.c_str( ) , QCreate1.size( ) ) != 0 )
                {
                    eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                    elothread = NULL;
                    Sleep( 1000 );
                    return 0;
                }

                if ( mysql_real_query( Connection , QCreate2.c_str( ) , QCreate2.size( ) ) != 0 )
                {
                    eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                    elothread = NULL;
                    Sleep( 1000 );
                    return 0;
                }

                cout << "getting unscored games" << endl;

                queue<GamesStr> UnscoredGames;

                string QSelectUnscored = "SELECT id, duration, gamename FROM games WHERE id NOT IN ( SELECT gameid FROM dota_elo_games_scored ) ORDER BY id";

                if ( mysql_real_query( Connection , QSelectUnscored.c_str( ) , QSelectUnscored.size( ) ) != 0 )
                {
                    eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                    elothread = NULL;
                    Sleep( 1000 );
                    return 0;
                }
                else
                {
                    MYSQL_RES *Result = mysql_store_result( Connection );

                    if ( Result )
                    {
                        vector<string> Row = MySQLFetchRow( Result );

                        while ( Row.size( ) == 3 )
                        {
                            GamesStr tmpgmstr;
                            tmpgmstr.gameid = UTIL_ToUInt32( Row[ 0 ].c_str( ) );
                            tmpgmstr.duration = UTIL_ToUInt32( Row[ 1 ].c_str( ) );
                            tmpgmstr.gamename = Row[ 2 ];

                            UnscoredGames.push( tmpgmstr );
                            Row = MySQLFetchRow( Result );
                        }

                        mysql_free_result( Result );
                    }
                    else
                    {
                        eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                        elothread = NULL;
                        Sleep( 1000 );
                        return 0;
                    }
                }

                cout << "found " << UnscoredGames.size( ) << " unscored games" << endl;

                while ( !UnscoredGames.empty( ) )
                {
                    Sleep( 2000 );
                    GamesStr curgamestr = UnscoredGames.front( );

                    unsigned int GameID = curgamestr.gameid;
                    UnscoredGames.pop( );

                    string QSelectPlayers = "SELECT dota_elo_scores.id, gameplayers.name, spoofedrealm, newcolour, winner, score, streak, leaves, gameplayers.left FROM dotaplayers LEFT JOIN dotagames ON dotagames.gameid=dotaplayers.gameid LEFT JOIN gameplayers ON gameplayers.gameid=dotaplayers.gameid AND gameplayers.colour=dotaplayers.colour LEFT JOIN dota_elo_scores ON dota_elo_scores.name=gameplayers.name AND server=spoofedrealm WHERE dotaplayers.gameid=" + UTIL_ToString( GameID );

                    if ( mysql_real_query( Connection , QSelectPlayers.c_str( ) , QSelectPlayers.size( ) ) != 0 )
                    {
                        eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                        elothread = NULL;
                        Sleep( 1000 );
                        return 0;
                    }
                    else
                    {
                        MYSQL_RES *Result = mysql_store_result( Connection );

                        if ( Result )
                        {
                            cout << "gameid " << UTIL_ToString( GameID ) << " found" << endl;

                            bool ignore = false;
                            unsigned int rowids[ 10 ];
                            string names[ 10 ];
                            string servers[ 10 ];
                            t_account * playeraccounts[ 10 ];
                            bool exists[ 10 ];
                            int num_players = 0;
                            float player_ratings[ 10 ];
                            int player_teams[ 10 ];
                            int player_streaks[ 10 ];
                            unsigned int player_leaves[ 10 ];
                            int num_teams = 2;
                            float team_ratings[ 2 ];
                            float team_winners[ 2 ];
                            int team_numplayers[ 2 ];
                            team_ratings[ 0 ] = 0.0;
                            team_ratings[ 1 ] = 0.0;
                            team_numplayers[ 0 ] = 0;
                            team_numplayers[ 1 ] = 0;

                            vector<string> Row = MySQLFetchRow( Result );

                            while ( Row.size( ) == 9 )
                            {
                                if ( num_players = 0 )
                                {
                                    cout << "gameid " << UTIL_ToString( GameID ) << " has more than 10 players, ignoring" << endl;
                                    ignore = true;
                                    break;
                                }

                                unsigned int Winner = UTIL_ToUInt32( Row[ 4 ].c_str( ) );

                                if ( Winner != 1 && Winner != 2 )
                                {
                                    cout << "gameid " << UTIL_ToString( GameID ) << " has no winner, ignoring" << endl;
                                    ignore = true;
                                    break;
                                }
                                else if ( Winner == 1 )
                                {
                                    team_winners[ 0 ] = 1.0;
                                    team_winners[ 1 ] = 0.0;
                                }
                                else
                                {
                                    team_winners[ 0 ] = 0.0;
                                    team_winners[ 1 ] = 1.0;
                                }

                                if ( !Row[ 0 ].empty( ) )
                                    rowids[ num_players ] = UTIL_ToUInt32( Row[ 0 ].c_str( ) );
                                else
                                    rowids[ num_players ] = 0;

                                names[ num_players ] = Row[ 1 ];
                                servers[ num_players ] = Row[ 2 ];

                                t_account * curplacc;


                                if ( !( curplacc = accountlist_find_account( names[ num_players ].c_str( ) ) ) )
                                {
                                    playeraccounts[ num_players ] = NULL;
                                    if ( !Row[ 5 ].empty( ) )
                                    {
                                        exists[ num_players ] = true;
                                        player_ratings[ num_players ] = UTIL_ToFloat( Row[ 5 ].c_str( ) );
                                    }
                                    else
                                    {
                                        cout << "new player [" << Row[ 1 ] << "] found" << endl;
                                        exists[ num_players ] = false;
                                        player_ratings[ num_players ] = 1000.0;
                                    }

                                    if ( !Row[ 6 ].empty( ) )
                                    {
                                        player_streaks[ num_players ] = UTIL_ToInt32( Row[ 6 ].c_str( ) );
                                    }
                                    else
                                    {
                                        player_streaks[ num_players ] = 0;
                                    }

                                    if ( !Row[ 7 ].empty( ) )
                                    {
                                        player_leaves[ num_players ] = UTIL_ToUInt32( Row[ 7 ].c_str( ) );
                                    }
                                    else
                                    {
                                        player_leaves[ num_players ] = 0;
                                    }



                                }
                                else
                                {
                                    playeraccounts[ num_players ] = curplacc;
                                    player_ratings[ num_players ] = account_get_pts( curplacc );
                                    player_streaks[ num_players ] = account_get_streak( curplacc );
                                    player_leaves[ num_players ] = account_get_leaves( curplacc );
                                }




                                if ( !Row[ 8 ].empty( ) )
                                {
                                    uint32_t playerleft = UTIL_ToInt32( Row[ 8 ].c_str( ) );

                                    if ( curgamestr.duration - playerleft > 5 * 60 )
                                        player_leaves[ num_players ]++;


                                }

                                unsigned int Colour = UTIL_ToUInt32( Row[ 3 ].c_str( ) );

                                if ( Colour >= 1 && Colour <= 5 )
                                {
                                    player_teams[ num_players ] = 0;


                                    team_ratings[ 0 ] += player_ratings[ num_players ];
                                    team_numplayers[ 0 ]++;
                                }
                                else if ( Colour >= 7 && Colour <= 11 )
                                {
                                    player_teams[ num_players ] = 1;
                                    team_ratings[ 1 ] += player_ratings[ num_players ];
                                    team_numplayers[ 1 ]++;
                                }
                                else
                                {
                                    cout << "gameid " << UTIL_ToString( GameID ) << " has a player with an invalid newcolour, ignoring" << endl;
                                    ignore = true;
                                    break;
                                }

                                if ( team_winners[ player_teams[ num_players ] ] == 1.0 )
                                {
                                    if ( player_streaks[ num_players ] < 0 )
                                        player_streaks[ num_players ] = 1;
                                    else
                                        player_streaks[ num_players ] ++;
                                }
                                else
                                {
                                    if ( player_streaks[ num_players ] > 0 )
                                        player_streaks[ num_players ] = -1;
                                    else
                                        player_streaks[ num_players ] --;
                                }

                                num_players++;
                                Row = MySQLFetchRow( Result );
                            }

                            mysql_free_result( Result );



                            if ( curgamestr.duration < 60 * 5 )
                            {
                                for ( int i = 0; i < num_players; i++ )
                                {
                                    char * tempmessage = new char[ MAX_MESSAGE_LEN ];
                                    snprintf( tempmessage , MAX_MESSAGE_LEN , " Game %s - ignored! Duration < 5 min!" , curgamestr.gamename.c_str( ) );
                                    sendmsgforplayername( tempmessage , names[ i ].c_str( ) );
                                    delete[ ] tempmessage;
                                }
                                ignore = true;
                            }


                            if ( !ignore )
                            {
                                if ( num_players == 0 )
                                    cout << "gameid " << UTIL_ToString( GameID ) << " has no players, ignoring" << endl;
                                else if ( team_numplayers[ 0 ] == 0 )
                                    cout << "gameid " << UTIL_ToString( GameID ) << " has no Sentinel players, ignoring" << endl;
                                else if ( team_numplayers[ 1 ] == 0 )
                                    cout << "gameid " << UTIL_ToString( GameID ) << " has no Scourge players, ignoring" << endl;
                                else
                                {
                                    cout << "gameid " << UTIL_ToString( GameID ) << " is calculating" << endl;

                                    float old_player_ratings[ 10 ];
                                    memcpy( old_player_ratings , player_ratings , sizeof( float ) * 10 );
                                    team_ratings[ 0 ] /= team_numplayers[ 0 ];
                                    team_ratings[ 1 ] /= team_numplayers[ 1 ];
                                    elo_recalculate_ratings( num_players , player_ratings , player_teams , num_teams , team_ratings , player_leaves , player_streaks , team_winners );

                                    for ( int i = 0; i < num_players; i++ )
                                    {
                                        cout << "player [" << names[ i ] << "] rating " << UTIL_ToString( ( unsigned int ) old_player_ratings[ i ] ) << " -> " << UTIL_ToString( ( unsigned int ) player_ratings[ i ] ) << endl;

                                        if ( exists[ i ] )
                                        {
                                            string QUpdateScore;//= "UPDATE dota_elo_scores SET score=" + UTIL_ToString( player_ratings[ i ] , 2 ) + " WHERE id=" + UTIL_ToString( rowids[ i ] );
                                            QUpdateScore = "UPDATE dota_elo_scores SET score=" + UTIL_ToString( player_ratings[ i ] , 2 ) + ", streak=" + UTIL_ToString( player_streaks[ i ] ) + ", leaves=" + UTIL_ToString( player_leaves[ i ] ) + " WHERE id=" + UTIL_ToString( rowids[ i ] );
                                            if ( mysql_real_query( Connection , QUpdateScore.c_str( ) , QUpdateScore.size( ) ) != 0 )
                                            {
                                                eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                                                elothread = NULL;
                                                Sleep( 1000 );
                                                return 0;
                                            }
                                        }
                                        else
                                        {
                                            string EscName = MySQLEscapeString( Connection , names[ i ] );
                                            string EscServer = MySQLEscapeString( Connection , servers[ i ] );
                                            string QInsertScore; //= "INSERT INTO dota_elo_scores ( name, server, score ) VALUES ( '" + EscName + "', '" + EscServer + "', " + UTIL_ToString( player_ratings[ i ] , 2 ) + " )";
                                            QInsertScore = "INSERT INTO dota_elo_scores ( name, server, score, streak, leaves ) VALUES ( '" + EscName + "', '" + EscServer + "', " + UTIL_ToString( player_ratings[ i ] , 2 ) + ", " + UTIL_ToString( player_streaks[ i ] ) + ", " + UTIL_ToString( player_leaves[ i ] ) + " )";
                                            if ( mysql_real_query( Connection , QInsertScore.c_str( ) , QInsertScore.size( ) ) != 0 )
                                            {
                                                eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                                                elothread = NULL;
                                                Sleep( 1000 );
                                                return 0;
                                            }
                                        }

                                        if ( playeraccounts[ i ] != NULL )
                                        {
                                            int oldptsvar = account_get_pts( playeraccounts[ i ] );

                                            char * newstateinf = new char[ MAX_MESSAGE_LEN ];
                                            snprintf( newstateinf , MAX_MESSAGE_LEN , "Player:%s , OLD PTS:%d , NEW PTS:%d" , account_get_name( playeraccounts[ i ] ) , oldptsvar , account_get_pts( playeraccounts[ i ] ) );
                                            LadderLogAddText( newstateinf );
                                            delete[ ]newstateinf;
                                            account_set_pts( playeraccounts[ i ] , player_ratings[ i ] );
                                            account_set_leaves( playeraccounts[ i ] , player_leaves[ i ] );

                                            if ( team_winners[ player_teams[ i ] ] == 1.0 )
                                            {
                                                //unsigned int playerminstreak = account_get_minstreak( playeraccounts[ i ] );
                                                int playermaxstreak = account_get_maxstreak( playeraccounts[ i ] );
                                                int playerstreak = account_get_streak( playeraccounts[ i ] );

                                                if ( playerstreak < 0 )
                                                    playerstreak = 1;
                                                else
                                                    playerstreak++;

                                                if ( playermaxstreak < playerstreak )
                                                    playermaxstreak = playerstreak;

                                                account_set_maxstreak( playeraccounts[ i ] , playermaxstreak );
                                                account_set_streak( playeraccounts[ i ] , playerstreak );

                                                account_set_wins( playeraccounts[ i ] , account_get_wins( playeraccounts[ i ] ) + 1 );

                                                t_connection * tempplcn;

                                                if ( !( tempplcn = account_get_conn( playeraccounts[ i ] ) ) )
                                                    ;
                                                else
                                                {
                                                    char * tempmsgc = new char[ MAX_MESSAGE_LEN ];
                                                    snprintf( tempmsgc , MAX_MESSAGE_LEN , " You new stats-> Streak:%d , Wins:%u, Looses:%u, Pts:%d" , account_get_streak( playeraccounts[ i ] ) , account_get_wins( playeraccounts[ i ] ) , account_get_looses( playeraccounts[ i ] ) , account_get_pts( playeraccounts[ i ] ) );


                                                    sendmsgforplayername( tempmsgc , names[ i ].c_str( ) );



                                                    delete[ ] tempmsgc;
                                                }


                                            }
                                            else
                                            {
                                                account_set_looses( playeraccounts[ i ] , account_get_looses( playeraccounts[ i ] ) + 1 );
                                                int playerminstreak = account_get_minstreak( playeraccounts[ i ] );

                                                int playerstreak = account_get_streak( playeraccounts[ i ] );

                                                if ( playerstreak > 0 )
                                                    playerstreak = -1;
                                                else
                                                    playerstreak--;

                                                if ( playerminstreak > playerstreak )
                                                    playerminstreak = playerstreak;

                                                account_set_minstreak( playeraccounts[ i ] , playerminstreak );
                                                account_set_streak( playeraccounts[ i ] , playerstreak );
                                            }





                                        }


                                    }
                                }
                            }
                        }
                        else
                        {
                            eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                            elothread = NULL;
                            Sleep( 1000 );
                            return 0;
                        }
                    }

                    string QInsertScored = "INSERT INTO dota_elo_games_scored ( gameid ) VALUES ( " + UTIL_ToString( GameID ) + " )";

                    if ( mysql_real_query( Connection , QInsertScored.c_str( ) , QInsertScored.size( ) ) != 0 )
                    {
                        eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                        elothread = NULL;
                        Sleep( 1000 );
                        return 0;
                    }
                }

                cout << "copying dota elo scores to scores table" << endl;

                string QCopyScores1 = "DELETE FROM scores WHERE category='dota_elo'";
                string QCopyScores2;//= "INSERT INTO scores ( category, name, server, score ) SELECT 'dota_elo', name, server, score FROM dota_elo_scores";
                QCopyScores2 = "INSERT INTO scores ( category, name, server, score, streak, leaves ) SELECT 'dota_elo', name, server, score, streak, leaves FROM dota_elo_scores";
                if ( mysql_real_query( Connection , QCopyScores1.c_str( ) , QCopyScores1.size( ) ) != 0 )
                {
                    eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                    elothread = NULL;
                    Sleep( 1000 );
                    return 0;
                }

                if ( mysql_real_query( Connection , QCopyScores2.c_str( ) , QCopyScores2.size( ) ) != 0 )
                {
                    eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                    elothread = NULL;
                    Sleep( 1000 );
                    return 0;
                }

                cout << "committing transaction" << endl;

                string QCommit = "COMMIT";

                if ( mysql_real_query( Connection , QCommit.c_str( ) , QCommit.size( ) ) != 0 )
                {
                    eventlog( eventlog_level_error , __FUNCTION__ , "-> %s" , mysql_error( Connection ) );
                    elothread = NULL;
                    Sleep( 1000 );
                    return 0;
                }

                cout << "done" << endl;
            }


            return 0;
        }

    }

}

Это кусок кода, где по команде /start происходит коннект к базе данных, чекаются новые игры, и подсчитываются.
Если Вам интересно, могу скинуть целый код.

2

Re: Помогите поправить.

Стороннему человеку найти такой баг в стороннем коде с закрытой реализацией всего решения, без тестирования на рабочем сервере очень сложно, этим никто заниматься не будет.
Если код подсчета статистики (который судя по всему и выложен выше) правильный, то тебе нужно проверять в том месте, где он совмещен с PvPGN. Если дебаг невозможен, то логировать как можно больше событий, изучать получившиеся логи, и править код соответственно.

Do not ask for support in PM.

Posts: 2

Pages 1

You must login or register to post a reply

Who now at forum

Currently view post: 0 guests, 0 registered users

forums.pvpgn.pro → [RU] The Source Code → Помогите поправить.