예제 #1
0
long BattleRoomTab::AddMMOptionsToList(long pos, LSL::Enum::GameOption optFlag)
{
	if (!m_battle)
		return -1;
	LSL::OptionsWrapper::stringTripleVec optlist = m_battle->CustomBattleOptions().getOptions(optFlag);
	for (LSL::OptionsWrapper::stringTripleVec::const_iterator it = optlist.begin(); it != optlist.end(); ++it) {
		m_opts_list->InsertItem(pos, TowxString(it->second.first));
		wxString tag = wxString::Format(_T( "%d_%s" ), optFlag, TowxString(it->first).c_str());
		m_opt_list_map[tag] = pos;
		UpdateBattleInfo(tag);
		pos++;
	}
	return pos;
}
예제 #2
0
파일: spring.cpp 프로젝트: N0U/lsl
std::string Spring::WriteScriptTxt( const IBattlePtr battle ) const
{
    std::stringstream ret;

    TDF::TDFWriter tdf(ret);

    // Start generating the script.
    tdf.EnterSection( "GAME" );

    tdf.Append( "HostIP", battle->GetHostIp() );
    if ( battle->IsFounderMe() )
    {
        if ( battle->GetNatType() == Enum::NAT_Hole_punching )
            tdf.Append( "HostPort", battle->GetMyInternalUdpSourcePort() );
        else
            tdf.Append("HostPort", battle->GetHostPort() );
    }
    else
    {
        tdf.Append( "HostPort", battle->GetHostPort() );
        if ( battle->GetNatType() == Enum::NAT_Hole_punching )
        {
            tdf.Append( "SourcePort", battle->GetMyInternalUdpSourcePort() );
        }
        else if ( sett().GetClientPort() != 0)
        {
            tdf.Append( "SourcePort", sett().GetClientPort() ); /// this allows to play with broken router by setting SourcePort to some forwarded port.
        }
    }
    tdf.Append( "IsHost", battle->IsFounderMe() );

    const ConstCommonUserPtr  me = battle->GetMe();
    tdf.Append("MyPlayerName", me->Nick() );

    if ( !me->BattleStatus().scriptPassword.empty() )
    {
        tdf.Append( "MyPasswd", me->BattleStatus().scriptPassword );
    }

    if ( !battle->IsFounderMe() )
    {
        tdf.LeaveSection();
        return ret.str();
    }

    /**********************************************************************************
                                                                        Host-only section
            **********************************************************************************/

    tdf.AppendLineBreak();

    tdf.Append("ModHash", battle->LoadMod().hash );
    tdf.Append("MapHash", battle->LoadMap().hash );

    tdf.Append( "Mapname", battle->GetHostMapName() );
    tdf.Append( "GameType", battle->GetHostModName() );

    tdf.AppendLineBreak();

    switch ( battle->GetBattleType() )
    {
    case Enum::BT_Played: break;
    case Enum::BT_Replay:
    {
        std::string path = battle->GetPlayBackFilePath();
        //!TODO this did nothing with wx?!?
//        if ( path.find("/") != std::string::npos )
//            path.BeforeLast('/');
        tdf.Append( "DemoFile", path );
        tdf.AppendLineBreak();
        break;
    }
    case Enum::BT_Savegame:
    {
        std::string path = battle->GetPlayBackFilePath();
        //!TODO this did nothing with wx?!?
//        if ( path.find("/") != std::string::npos )
//            path.BeforeLast('/');
        tdf.Append( "Savefile", path );
        tdf.AppendLineBreak();
        break;
    }
    default:
        break;
    }

    long startpostype = Util::FromString<long>(
            battle->CustomBattleOptions()->getSingleValue( "startpostype", LSL::OptionsWrapper::EngineOption ) );

    std::vector<StartPos> remap_positions;
    if ( battle->IsProxy() && ( startpostype != Enum::ST_Pick ) && ( startpostype != Enum::ST_Choose ) )
    {
        std::set<int> parsedteams;
        unsigned int NumTeams = 0;
        for( const ConstCommonUserPtr usr: battle->Users() )
        {
            const UserBattleStatus& status = usr->BattleStatus();
            if ( status.spectator )
                continue;
            if ( parsedteams.find( status.team ) != parsedteams.end() )
                continue; // skip duplicates
            parsedteams.insert( status.team );
            NumTeams++;
        }

        MapInfo infos = battle->LoadMap().info;
        unsigned int nummapstartpositions = infos.positions.size();
        unsigned int copysize = std::min( nummapstartpositions, NumTeams );
        remap_positions = std::vector<StartPos> ( infos.positions.begin(), infos.positions.begin() + copysize ); // only add the first x positions

        if ( startpostype == Enum::ST_Random )
        {
            random_shuffle( remap_positions.begin(), remap_positions.end() ); // shuffle the positions
        }

    }
    if ( battle->IsProxy() )
    {
        if ( ( startpostype == Enum::ST_Random ) || ( startpostype == Enum::ST_Fixed ) )
        {
            tdf.Append( "startpostype", Enum::ST_Pick );
        }
        else tdf.Append( "startpostype", startpostype );
    }
    else tdf.Append( "startpostype", startpostype );

    tdf.EnterSection( "mapoptions" );
    LSL::OptionsWrapper::stringTripleVec optlistMap = battle->CustomBattleOptions()->getOptions( LSL::OptionsWrapper::MapOption );
    for (LSL::OptionsWrapper::stringTripleVec::const_iterator it = optlistMap.begin(); it != optlistMap.end(); ++it)
    {
        tdf.Append(it->first,it->second.second);
    }
    tdf.LeaveSection();


    tdf.EnterSection("modoptions");
    tdf.Append( "relayhoststartpostype", startpostype ); // also save the original wanted setting
    LSL::OptionsWrapper::stringTripleVec optlistMod = battle->CustomBattleOptions()->getOptions( LSL::OptionsWrapper::ModOption );
    for (LSL::OptionsWrapper::stringTripleVec::const_iterator it = optlistMod.begin(); it != optlistMod.end(); ++it)
    {
        tdf.Append(it->first,it->second.second);
    }
    tdf.LeaveSection();

    std::map<std::string,int> units = battle->RestrictedUnits();
    tdf.Append( "NumRestrictions", units.size());
    tdf.EnterSection( "RESTRICT" );
    int restrictcount = 0;
    for ( std::map<std::string, int>::const_iterator itor = units.begin(); itor != units.end(); ++itor )
    {
        tdf.Append("Unit" + Util::ToString( restrictcount ), itor->first );
        tdf.Append("Limit" + Util::ToString( restrictcount ), itor->second );
        restrictcount++;
    }
    tdf.LeaveSection();


    tdf.AppendLineBreak();

    if ( battle->IsProxy() )
    {
        tdf.Append( "NumPlayers", battle->GetNumPlayers() -1 );
        tdf.Append( "NumUsers", battle->GetNumUsers() -1 );
    }
    else
    {
        tdf.Append( "NumPlayers", battle->GetNumPlayers() );
        tdf.Append( "NumUsers", battle->GetNumUsers() );
    }
    tdf.AppendLineBreak();

    typedef std::map<int, int> ProgressiveTeamsVec;
    typedef ProgressiveTeamsVec::iterator ProgressiveTeamsVecIter;
    ProgressiveTeamsVec teams_to_sorted_teams; // original team -> progressive team
    int free_team = 0;
    std::map<const ConstCommonUserPtr, int> player_to_number; // player -> ordernumber
    srand ( time(NULL) );
    int i = 0;
    const unsigned int NumUsers = battle->Users().size();
    for( const ConstCommonUserPtr user: battle->Users() )
    {
        const UserBattleStatus& status = user->BattleStatus();
        if ( !status.spectator )
        {
            ProgressiveTeamsVecIter itor = teams_to_sorted_teams.find ( status.team );
            if ( itor == teams_to_sorted_teams.end() )
            {
                teams_to_sorted_teams[status.team] = free_team;
                free_team++;
            }
        }
        if ( battle->IsProxy() && ( user->Nick() == battle->GetFounder()->Nick() ) ) continue;
        if ( status.IsBot() ) continue;
        tdf.EnterSection( "PLAYER" + Util::ToString( i ) );
        tdf.Append( "Name", user->Nick() );
        tdf.Append( "CountryCode", BA::to_lower_copy( user->GetCountry() ) );
        tdf.Append( "Spectator", status.spectator );
        tdf.Append( "Rank", (int)user->GetRank() );
        tdf.Append( "IsFromDemo", int(status.isfromdemo) );
        if ( !status.scriptPassword.empty() )
        {
            tdf.Append( "Password", status.scriptPassword );
        }
        if ( !status.spectator )
        {
            tdf.Append( "Team", teams_to_sorted_teams[status.team] );
        }
        else
        {
            int speccteam = 0;
            if ( !teams_to_sorted_teams.empty() )
                speccteam = rand() % teams_to_sorted_teams.size();
            tdf.Append( "Team", speccteam );
        }
        tdf.LeaveSection();
        player_to_number[user] = i;
        i++;
    }

    if ( usync().VersionSupports( LSL::USYNC_GetSkirmishAI ) )
    {
        unsigned int i = 0;
        for( const ConstCommonUserPtr user: battle->Users() )
        {
            const UserBattleStatus& status = user->BattleStatus();
            if ( !status.IsBot() ) continue;
            tdf.EnterSection( "AI" + Util::ToString( i ) );
            tdf.Append( "Name", user->Nick() ); // AI's nick;
            tdf.Append( "ShortName", status.aishortname ); // AI libtype
            tdf.Append( "Version", status.aiversion ); // AI libtype version
            tdf.Append( "Team", teams_to_sorted_teams[status.team] );
            tdf.Append( "IsFromDemo", int(status.isfromdemo) );
            tdf.Append( "Host", player_to_number[battle->GetUser( status.owner )] );
            tdf.EnterSection( "Options" );
            int optionmapindex = battle->CustomBattleOptions()->GetAIOptionIndex( user->Nick() );
            if ( optionmapindex > 0 )
            {
                LSL::OptionsWrapper::stringTripleVec optlistMod_ = battle->CustomBattleOptions()->getOptions( (LSL::OptionsWrapper::GameOption)optionmapindex );
                for (LSL::OptionsWrapper::stringTripleVec::const_iterator it = optlistMod_.begin(); it != optlistMod_.end(); ++it)
                {
                    tdf.Append(it->first,it->second.second);
                }
            }
            tdf.LeaveSection();
            tdf.LeaveSection();
            player_to_number[user] = i;
            i++;
        }
    }

    tdf.AppendLineBreak();

    std::set<int> parsedteams;
    StringVector sides = usync().GetSides( battle->GetHostModName() );
    for( const ConstCommonUserPtr usr: battle->Users() )
    {
        const UserBattleStatus& status = usr->BattleStatus();
        if ( status.spectator ) continue;
        if ( parsedteams.find( status.team ) != parsedteams.end() ) continue; // skip duplicates
        parsedteams.insert( status.team );

        tdf.EnterSection( "TEAM" + Util::ToString( teams_to_sorted_teams[status.team] ) );
        if ( !usync().VersionSupports( LSL::USYNC_GetSkirmishAI ) && status.IsBot() )
        {
            tdf.Append( "AIDLL", status.aishortname );
            tdf.Append( "TeamLeader", player_to_number[battle->GetUser( status.owner )] ); // bot owner is the team leader
        }
        else
        {
            if ( status.IsBot() )
            {
                tdf.Append( "TeamLeader", player_to_number[battle->GetUser( status.owner )] );
            }
            else
            {
                tdf.Append( "TeamLeader", player_to_number[usr] );
            }
        }
        if ( battle->IsProxy() )
        {
            if ( startpostype == Enum::ST_Pick )
            {
                tdf.Append("StartPosX", status.pos.x );
                tdf.Append("StartPosZ", status.pos.y );
            }
            else if ( ( startpostype == Enum::ST_Fixed ) || ( startpostype == Enum::ST_Random ) )
            {
                int teamnumber = teams_to_sorted_teams[status.team];
                if ( teamnumber < int(remap_positions.size()) ) // don't overflow
                {
                    StartPos position = remap_positions[teamnumber];
                    tdf.Append("StartPosX", position.x );
                    tdf.Append("StartPosZ", position.y );
                }
            }
        }
        else
        {
            if ( startpostype == Enum::ST_Pick )
            {
                tdf.Append("StartPosX", status.pos.x );
                tdf.Append("StartPosZ", status.pos.y );
            }
        }

        tdf.Append( "AllyTeam",status.ally );

        std::string colorstring =
                Util::ToString( status.color.Red()/255.0 ) + ' ' +
                Util::ToString( status.color.Green()/255.0 ) + ' ' +
                Util::ToString( status.color.Blue()/255.0 );
        tdf.Append( "RGBColor", colorstring);

        unsigned int side = status.side;
        if ( side < sides.size() ) tdf.Append( "Side", sides[side] );
        tdf.Append( "Handicap", status.handicap );
        tdf.LeaveSection();
    }

    tdf.AppendLineBreak();

    unsigned int maxiter = std::max( NumUsers, battle->GetLastRectIdx() + 1 );
    std::set<int> parsedallys;
    for ( unsigned int i = 0; i < maxiter; i++ )
    {
        const ConstCommonUserPtr  usr = battle->Users()[i];
        const UserBattleStatus& status = usr->BattleStatus();
        Battle::BattleStartRect sr = battle->GetStartRect( i );
        if ( status.spectator && !sr.IsOk() )
            continue;
        int ally = status.ally;
        if ( status.spectator )
            ally = i;
        if ( parsedallys.find( ally ) != parsedallys.end() )
            continue; // skip duplicates
        sr = battle->GetStartRect( ally );
        parsedallys.insert( ally );

        tdf.EnterSection( "ALLYTEAM" + Util::ToString( ally ) );
        tdf.Append( "NumAllies", 0 );
        if ( startpostype == Enum::ST_Choose )
        {
            if ( sr.IsOk() )
            {
                const char* old_locale = std::setlocale(LC_NUMERIC, "C");

                tdf.Append( "StartRectLeft", boost::format( "%.3f" ) % ( sr.left / 200.0 ) );
                tdf.Append( "StartRectTop", boost::format( "%.3f" ) % ( sr.top / 200.0 ) );
                tdf.Append( "StartRectRight", boost::format( "%.3f" ) % ( sr.right / 200.0 ) );
                tdf.Append( "StartRectBottom", boost::format( "%.3f" ) % ( sr.bottom / 200.0 ) );

                std::setlocale(LC_NUMERIC, old_locale);
            }
        }
        tdf.LeaveSection();
    }

    tdf.LeaveSection();

    return ret.str();
}