void ResourcePool::Update() {
    //DebugLogger() << "ResourcePool::Update for type " << boost::lexical_cast<std::string>(m_type);
    // sum production from all ResourceCenters in each group, for resource point type appropriate for this pool
    MeterType meter_type = ResourceToMeter(m_type);
    MeterType target_meter_type = ResourceToTargetMeter(m_type);

    if (INVALID_METER_TYPE == meter_type || INVALID_METER_TYPE == target_meter_type)
        ErrorLogger() << "ResourcePool::Update() called when m_type can't be converted to a valid MeterType";

    // zero to start...
    m_connected_object_groups_resource_output.clear();
    m_connected_object_groups_resource_target_output.clear();

    // temporary storage: indexed by group of systems, which objects
    // are located in that system group?
    std::map<std::set<int>, std::set<std::shared_ptr<const UniverseObject>>>
        system_groups_to_object_groups;


    // for every object, find if a connected system group contains the object's
    // system.  If a group does, place the object into that system group's set
    // of objects.  If no group contains the object, place the object in its own
    // single-object group.
    for (auto& obj : Objects().FindObjects<const UniverseObject>(m_object_ids)) {
        int object_id = obj->ID();
        int object_system_id = obj->SystemID();
        // can't generate resources when not in a system
        if (object_system_id == INVALID_OBJECT_ID)
            continue;

        // is object's system in a system group?
        std::set<int> object_system_group;
        for (const auto& sys_group : m_connected_system_groups) {
            if (sys_group.find(object_system_id) != sys_group.end()) {
                object_system_group = sys_group;
                break;
            }
        }

        // if object's system is not in a system group, add it as its
        // own entry in m_connected_object_groups_resource_output and m_connected_object_groups_resource_target_output
        // this will allow the object to use its own locally produced
        // resource when, for instance, distributing pp
        if (object_system_group.empty()) {
            object_system_group.insert(object_id);  // just use this already-available set to store the object id, even though it is not likely actually a system

            float obj_output = obj->GetMeter(meter_type) ? obj->CurrentMeterValue(meter_type) : 0.0f;
            m_connected_object_groups_resource_output[object_system_group] = obj_output;

            float obj_target_output = obj->GetMeter(target_meter_type) ? obj->CurrentMeterValue(target_meter_type) : 0.0f;
            m_connected_object_groups_resource_target_output[object_system_group] = obj_target_output;
            continue;
        }

        // if resource center's system is in a system group, record which system
        // group that is for later
        system_groups_to_object_groups[object_system_group].insert(obj);
    }

    // sum the resource production for object groups, and store the total
    // group production, indexed by group of object ids
    for (auto& entry : system_groups_to_object_groups) {
        const auto& object_group = entry.second;
        std::set<int> object_group_ids;
        float total_group_output = 0.0f;
        float total_group_target_output = 0.0f;
        for (auto& obj : object_group) {
            if (obj->GetMeter(meter_type))
                total_group_output += obj->CurrentMeterValue(meter_type);
            if (obj->GetMeter(target_meter_type))
                total_group_target_output += obj->CurrentMeterValue(target_meter_type);
            object_group_ids.insert(obj->ID());
        }
        m_connected_object_groups_resource_output[object_group_ids] = total_group_output;
        m_connected_object_groups_resource_target_output[object_group_ids] = total_group_target_output;
    }

    ChangedSignal();
}
int	cmdRemovePath(	ClientData	 client_data,
	       		Tcl_Interp	*interp,
	       		int		 argc,
	       		CONST84 char	*argv[])
{
    char	 *sw_marker = APP_SW_MARKER,	/** arbitrary default	     **/
		**pathlist;			/** List of dirs	     **/
    const char	 *delim = _colon;		/** path delimiter	     **/
    int		  numpaths,			/** number of dirs in path   **/
		  arg1 = 1,			/** arg start		     **/
		  x;				/** loop index		     **/


#if WITH_DEBUGGING_CALLBACK
    ErrorLogger( NO_ERR_START, LOC, _proc_cmdRemovePath, NULL);
#endif

    /**
     **   Check arguments. There should be give 3 args:
     **     argv[0]  -  prepend/append/remove-path
     **     ...
     **     argv[n-1]-  varname
     **     argv[n]  -  value
     **/
    if(argc < 3)
	if( OK != ErrorLogger(ERR_USAGE,LOC,argv[0],"path-variable directory",
	    NULL))
	    goto unwind0;


    /**
     **  Non-persist mode?
     **/

    if (g_flags & M_NONPERSIST) {
	return (TCL_OK);
    }

    /**
     **  Display only ... ok, let's do so!
     **/
    if(g_flags & M_DISPLAY) {
	fprintf( stderr, "%s\t ", argv[ 0]);
	while( --argc)
	    fprintf( stderr, "%s ", *++argv);
	fprintf( stderr, "\n");
        goto success0;
    }

    /**
     **  prepend or append. The default is append.
     **/
    if( ! strncmp( argv[0], "pre", 3))
	sw_marker = PRE_SW_MARKER;

    /**
     **  Check for the delimiter option
     **/
    if(*(argv[arg1]) == '-') {
	if (!strcmp(argv[arg1], "-d")) {
		delim = argv[arg1+1];
		arg1 += 2;
	} else if (!strcmp(argv[arg1], "--delim")) {
		delim = argv[arg1+1];
		arg1 += 2;
	} else if (!strncmp(argv[arg1], "--delim=", 8)) {
		delim = argv[arg1]+8;
		arg1++;
	}
    }

    /**
     ** For switch state3, we're looking to remove the markers.
     **/
    if( g_flags & M_SWSTATE3)
	argv[arg1+1] = sw_marker;

    /**
     **  Split the path into its components so each item can be removed
     **  individually from the variable.
     **/
    if( !( pathlist = SplitIntoList( interp, (char *) argv[arg1+1], &numpaths,
	delim)))
	goto unwind0;

    /**
     ** Remove each item individually
     **/
    for( x = 0; x < numpaths; x++)
	if(TCL_OK != Remove_Path(interp,(char *) argv[arg1],pathlist[x],
	sw_marker, delim))
	    goto unwind1;

#if WITH_DEBUGGING_CALLBACK
    ErrorLogger( NO_ERR_END, LOC, _proc_cmdRemovePath, NULL);
#endif

    /**
     ** Free resources
     **/
    FreeList(pathlist, numpaths);

success0:
    return( TCL_OK);			/** -------- EXIT (SUCCESS) -------> **/

unwind1:
    FreeList(pathlist, numpaths);
unwind0:
    return( TCL_ERROR);			/** -------- EXIT (FAILURE) -------> **/

} /** End of 'cmdRemovePath' **/
Exemple #3
0
std::string SupplyManager::Dump(int empire_id) const {
    std::string retval;

    try {
        for (const std::map<int, std::set<int>>::value_type& empire_supply : m_fleet_supplyable_system_ids) {
            if (empire_id != ALL_EMPIRES && empire_supply.first != empire_id)
                continue;
            retval += "Supplyable systems for empire " + std::to_string(empire_supply.first) + "\n";
            for (int system_id : empire_supply.second) {
                std::shared_ptr<const System> sys = GetSystem(system_id);
                if (!sys)
                    continue;
                retval += "\n" + sys->PublicName(empire_id) + " (" + std::to_string(sys->ID()) + ") ";

                retval += "\nTraversals from here to: ";

                for (const std::set<std::pair<int, int>>::value_type& trav : m_supply_starlane_traversals.at(empire_supply.first)) {
                    if (trav.first == sys->ID()) {
                        std::shared_ptr<const UniverseObject> obj = GetUniverseObject(trav.second);
                        if (obj)
                            retval += obj->PublicName(empire_id) + " (" + std::to_string(obj->ID()) + ")  ";
                    }
                }
                retval += "\n";

                retval += "Traversals to here from: ";
                for (const std::set<std::pair<int, int>>::value_type& trav : m_supply_starlane_traversals.at(empire_supply.first)) {
                    if (trav.second == sys->ID()) {
                        std::shared_ptr<const UniverseObject> obj = GetUniverseObject(trav.first);
                        if (obj)
                            retval += obj->PublicName(empire_id) + " (" + std::to_string(obj->ID()) + ")  ";
                    }
                }
                retval += "\n";

                retval += "Blocked Traversals from here to: ";
                for (const std::set<std::pair<int, int>>::value_type& trav : m_supply_starlane_obstructed_traversals.at(empire_supply.first)) {
                    if (trav.first == sys->ID()) {
                        std::shared_ptr<const UniverseObject> obj = GetUniverseObject(trav.second);
                        if (obj)
                            retval += obj->PublicName(empire_id) + " (" + std::to_string(obj->ID()) + ")  ";
                    }
                }
                retval += "\n";

                retval += "Blocked Traversals to here from: ";
                for (const std::set<std::pair<int, int>>::value_type& trav : m_supply_starlane_obstructed_traversals.at(empire_supply.first)) {
                    if (trav.second == sys->ID()) {
                        std::shared_ptr<const UniverseObject> obj = GetUniverseObject(trav.first);
                        if (obj)
                            retval += obj->PublicName(empire_id) + " (" + std::to_string(obj->ID()) + ")  ";
                    }
                }
                retval += "\n";

            }
            retval += "\n\n";
        }

        for (const std::map<int, std::set<std::set<int>>>::value_type& empire_supply : m_resource_supply_groups) {
            retval += "Supply groups for empire " + std::to_string(empire_supply.first) + "\n";
            for (const std::set<std::set<int>>::value_type& system_group : empire_supply.second) {
                retval += "group: ";
                for (int system_id : system_group) {
                    std::shared_ptr<const System> sys = GetSystem(system_id);
                    if (!sys)
                        continue;
                    retval += "\n" + sys->PublicName(empire_id) + " (" + std::to_string(sys->ID()) + ") ";
                }
                retval += "\n";
            }
            retval += "\n\n";
        }
    } catch (const std::exception& e) {
        ErrorLogger() << "SupplyManager::Dump caught exception: " << e.what();
    }

    return retval;
}
int	cmdSystem(	ClientData	 clientData, 
	  		Tcl_Interp	*interp, 
	  		int		 argc, 
	  		CONST84 char	*argv[])
{
    int		 i;
    int		 saved_stdout;
    char	 buf[ MAX_ARGLIST];
    char	*bufp = buf;
    int		 total_len = 0,
    		 arg_len;

#if WITH_DEBUGGING_CALLBACK
    ErrorLogger( NO_ERR_START, LOC, _proc_cmdSystem, NULL);
#endif

    /**
     **  Whatis mode
     **/

    if( g_flags & (M_WHATIS | M_HELP))
        return( TCL_OK);		/** -------- EXIT (SUCCESS) -------> **/

    /**
     **  Display mode?
     **/

    if( g_flags & M_DISPLAY) {
	fprintf( stderr, "%s\t\t ", argv[ 0]);
	for( i=1; i<argc; i++)
	    fprintf( stderr, "%s ", argv[ i]);
	fprintf( stderr, "\n");
        return( TCL_OK);		/** ------- EXIT PROCEDURE -------> **/
    }

    /**
     **  Prepare a buffer to hold the complete 'system' call
     **  Watch over the commands complete length while copying ...
     **/

    for( i = 1; i<argc; i++) {

        total_len += (1 + (arg_len = strlen(argv[i])));
        if( total_len > MAX_ARGLIST) {
	    if( OK != ErrorLogger( ERR_ARGSTOLONG, LOC, argv[0], (sprintf( buf,
		"%d", total_len), buf), NULL))
		return( TCL_ERROR);	/** -------- EXIT (FAILURE) -------> **/
        }

	/**
 	 **  Copy the argument ov the buffer and put a space at its end
	 **/

        memcpy( bufp, argv[i], arg_len);
        bufp += arg_len;
        memcpy( bufp, " ", 1);
        bufp += 1;
    }

    /**
     **  For Modules, stdout must be directed to stderr so it
     **  isn't parsed by the evaluating shell.  We also must save it here so it
     **  can be restored after this command has been executed.
     **/

    saved_stdout = TieStdout();

    *(bufp-1) = '\0';
    i = system( buf);

    /**
     **  Following the style of Tcl_ExecCmd, we can just return the
     **  raw result (appropriately shifted and masked) to Tcl
     **/

    sprintf( buf, "%d", (0xff & (i >> 8)));
    Tcl_SetResult( interp, buf, TCL_VOLATILE);

    /*
     *  Restore stdout.
     */

    UnTieStdout( saved_stdout);
    
#if WITH_DEBUGGING_CALLBACK
    ErrorLogger( NO_ERR_END, LOC, _proc_cmdSystem, NULL);
#endif

    return( TCL_OK);

} /** End of 'cmdSystem' **/
Exemple #5
0
void ShipDesign::BuildStatCaches() {
    const HullType* hull = GetHullType(m_hull);
    if (!hull) {
        ErrorLogger() << "ShipDesign::BuildStatCaches couldn't get hull with name " << m_hull;
        return;
    }

    m_producible =      hull->Producible();
    m_detection =       hull->Detection();
    m_colony_capacity = hull->ColonyCapacity();
    m_troop_capacity =  hull->TroopCapacity();
    m_stealth =         hull->Stealth();
    m_fuel =            hull->Fuel();
    m_shields =         hull->Shields();
    m_structure =       hull->Structure();
    m_speed =           hull->Speed();

    for (std::vector<std::string>::const_iterator it = m_parts.begin(); it != m_parts.end(); ++it) {
        if (it->empty())
            continue;

        const PartType* part = GetPartType(*it);
        if (!part) {
            ErrorLogger() << "ShipDesign::BuildStatCaches couldn't get part with name " << *it;
            continue;
        }

        if (!part->Producible())
            m_producible = false;

        switch (part->Class()) {
        case PC_SHORT_RANGE:
        case PC_MISSILES:
        case PC_FIGHTERS:
        case PC_POINT_DEFENSE: {
            m_is_armed = true;
            break;
        }
        case PC_COLONY:
            m_colony_capacity += part->Capacity();
            break;
        case PC_TROOPS:
            m_troop_capacity += part->Capacity();
            break;
        case PC_STEALTH:
            m_stealth += part->Capacity();
            break;
        case PC_SPEED:
            m_speed += part->Capacity();
            break;
        case PC_SHIELD:
            m_shields += part->Capacity();
            break;
        case PC_FUEL:
            m_fuel += part->Capacity();
            break;
        case PC_ARMOUR:
            m_structure += part->Capacity();
            break;
        case PC_DETECTION:
            m_detection += part->Capacity();
            break;
        case PC_BOMBARD:
            m_can_bombard = true;
            break;
        case PC_RESEARCH:
            m_research_generation += part->Capacity();
            break;
        case PC_INDUSTRY:
            m_industry_generation += part->Capacity();
            break;
        case PC_TRADE:
            m_trade_generation += part->Capacity();
            break;
        case PC_PRODICTION_LOCATION:
            m_is_production_location = true;
            break;
        default:
            break;
        }
    }
}
static void exchange( char **argv)
{
    int bottom = first_nonopt;
    int middle = last_nonopt;
    int top = optind;
    char *tem;

#ifdef _MODULES_DEF_H
#  if WITH_DEBUGGING_INIT
    ErrorLogger( NO_ERR_START, LOC, _proc_exchange, NULL);
#  endif
#endif

    /**
     **  Exchange the shorter segment with the far end of the longer segment.
     **  That puts the shorter segment into the right place.
     **  It leaves the longer segment in the right place overall,
     **  but it consists of two parts that need to be swapped next. 
     **/

    while( top > middle && middle > bottom) {
	if( top - middle > middle - bottom) {

	    /**
	     ** Bottom segment is the short one. 
	     **/

	    int len = middle - bottom;
	    register int i;

	    /**
	     **  Swap it with the top part of the top segment. 
	     **/

	    for( i = 0; i < len; i++) {
		tem = argv[bottom + i];
		argv[bottom + i] = argv[top -( middle - bottom) + i];
		argv[top -( middle - bottom) + i] = tem;
	    }

	    /**
	     **  Exclude the moved bottom segment from further swapping. 
	     **/

	    top -= len;

	} else {
	    
	    /**
	     **  Top segment is the short one. 
	     **/

	    int len = top - middle;
	    register int i;

	    /**
	     **  Swap it with the bottom part of the bottom segment. 
	     **/

	    for( i = 0; i < len; i++) {
		tem = argv[bottom + i];
		argv[bottom + i] = argv[middle + i];
		argv[middle + i] = tem;
	    }

	    /**
	     **  Exclude the moved top segment from further swapping. 
	     **/

	    bottom += len;
	}

    } /** while **/

    /**
     **  Update records for the slots the non-options now occupy. 
     **/

    first_nonopt +=( optind - last_nonopt);
    last_nonopt = optind;

#ifdef _MODULES_DEF_H
#  if WITH_DEBUGGING_INIT
    ErrorLogger( NO_ERR_END, LOC, _proc_exchange, NULL);
#  endif
#endif

} /** end of 'exchange' **/
void SpecialsPanel::Update() {
    //std::cout << "SpecialsPanel::Update" << std::endl;
    for (std::map<std::string, StatisticIcon*>::iterator it = m_icons.begin(); it != m_icons.end(); ++it)
        DeleteChild(it->second);
    m_icons.clear();


    // get specials to display
    TemporaryPtr<const UniverseObject> obj = GetUniverseObject(m_object_id);
    if (!obj) {
        ErrorLogger() << "SpecialsPanel::Update couldn't get object with id " << m_object_id;
        return;
    }
    const std::map<std::string, std::pair<int, float> >& specials = obj->Specials();


    // get specials and use them to create specials icons
    // for specials with a nonzero
    for (std::map<std::string, std::pair<int, float> >::const_iterator it = specials.begin(); it != specials.end(); ++it) {
        const Special* special = GetSpecial(it->first);
        StatisticIcon* graphic = 0;
        if (it->second.second > 0.0f)
            graphic = new StatisticIcon(ClientUI::SpecialIcon(special->Name()), it->second.second, 2, false);
        else
            graphic = new StatisticIcon(ClientUI::SpecialIcon(special->Name()));

        graphic->SetBrowseModeTime(GetOptionsDB().Get<int>("UI.tooltip-delay"));

        std::string desc = UserString(special->Description());

        if (it->second.second > 0.0f)
            desc += "\n" + boost::io::str(FlexibleFormat(UserString("SPECIAL_CAPACITY")) % DoubleToString(it->second.second, 2, false));

        if (it->second.first > 0)
            desc += "\n" + boost::io::str(FlexibleFormat(UserString("ADDED_ON_TURN")) % boost::lexical_cast<std::string>(it->second.first));
        else
            desc += "\n" + UserString("ADDED_ON_INITIAL_TURN");

        if (GetOptionsDB().Get<bool>("UI.autogenerated-effects-descriptions") && !special->Effects().empty()) {
            desc += boost::io::str(FlexibleFormat(UserString("ENC_EFFECTS_STR")) % AutoGeneratedDescription(special->Effects()));
        }

        graphic->SetBrowseInfoWnd(boost::shared_ptr<GG::BrowseInfoWnd>(
            new IconTextBrowseWnd(ClientUI::SpecialIcon(special->Name()),
                                  UserString(special->Name()),
                                  desc)));
        m_icons[it->first] = graphic;

        graphic->InstallEventFilter(this);
    }

    const GG::X AVAILABLE_WIDTH = Width() - EDGE_PAD;
    GG::X x(EDGE_PAD);
    GG::Y y(EDGE_PAD);

    for (std::map<std::string, StatisticIcon*>::iterator it = m_icons.begin(); it != m_icons.end(); ++it) {
        StatisticIcon* icon = it->second;
        icon->SizeMove(GG::Pt(x, y), GG::Pt(x,y) + GG::Pt(SPECIAL_ICON_WIDTH, SPECIAL_ICON_HEIGHT));
        AttachChild(icon);

        x += SPECIAL_ICON_WIDTH + EDGE_PAD;

        if (x + SPECIAL_ICON_WIDTH + EDGE_PAD > AVAILABLE_WIDTH) {
            x = GG::X(EDGE_PAD);
            y += SPECIAL_ICON_HEIGHT + EDGE_PAD;
        }
    }

    if (m_icons.empty()) {
        Resize(GG::Pt(Width(), GG::Y0));
    } else {
        Resize(GG::Pt(Width(), y + SPECIAL_ICON_HEIGHT + EDGE_PAD*2));
    }
}
Exemple #8
0
void SaveGame(const std::string& filename, const ServerSaveGameData& server_save_game_data,
              const std::vector<PlayerSaveGameData>& player_save_game_data, const Universe& universe,
              const EmpireManager& empire_manager, const SpeciesManager& species_manager,
              const CombatLogManager& combat_log_manager, const GalaxySetupData& galaxy_setup_data,
              bool multiplayer)
{
    ScopedTimer timer("SaveGame: " + filename, true);

    bool use_binary = GetOptionsDB().Get<bool>("binary-serialization");
    DebugLogger() << "SaveGame(" << (use_binary ? "binary" : "zlib-xml") << ") filename: " << filename;
    GetUniverse().EncodingEmpire() = ALL_EMPIRES;

    DebugLogger() << "Compiling save empire and preview data";
    std::map<int, SaveGameEmpireData> empire_save_game_data = CompileSaveGameEmpireData(empire_manager);
    SaveGamePreviewData save_preview_data;
    CompileSaveGamePreviewData(server_save_game_data, player_save_game_data, empire_save_game_data, save_preview_data);


    // reinterpret save game data as header data for uncompressed header
    std::vector<PlayerSaveHeaderData> player_save_header_data;
    for (std::vector<PlayerSaveGameData>::const_iterator it = player_save_game_data.begin();
         it != player_save_game_data.end(); ++it)
    { player_save_header_data.push_back(*it); }


    try {
        fs::path path = FilenameToPath(filename);
        // A relative path should be relative to the save directory.
        if (path.is_relative()) {
            path = GetSaveDir() / path;
            DebugLogger() << "Made save path relative to save dir. Is now: " << path;
        }

        if (multiplayer) {
            // Make sure the path points into our save directory
            if (!IsInside(path, GetSaveDir())) {
                path = GetSaveDir() / path.filename();
            }
        }

        // set up output archive / stream for saving
        fs::ofstream ofs(path, std::ios_base::binary);
        if (!ofs)
            throw std::runtime_error(UNABLE_TO_OPEN_FILE);

        if (use_binary) {
            DebugLogger() << "Creating binary oarchive";
            freeorion_bin_oarchive boa(ofs);
            boa << BOOST_SERIALIZATION_NVP(save_preview_data);
            boa << BOOST_SERIALIZATION_NVP(galaxy_setup_data);
            boa << BOOST_SERIALIZATION_NVP(server_save_game_data);
            boa << BOOST_SERIALIZATION_NVP(player_save_header_data);
            boa << BOOST_SERIALIZATION_NVP(empire_save_game_data);

            boa << BOOST_SERIALIZATION_NVP(player_save_game_data);
            boa << BOOST_SERIALIZATION_NVP(empire_manager);
            boa << BOOST_SERIALIZATION_NVP(species_manager);
            boa << BOOST_SERIALIZATION_NVP(combat_log_manager);
            Serialize(boa, universe);
            DebugLogger() << "Done serializing";

        } else {
            // Two-tier serialization:
            // main archive is uncompressed serialized header data first
            // then contains a string for compressed second archive
            // that contains the main gamestate info


            // allocate buffers for serialized gamestate
            DebugLogger() << "Allocating buffers for XML serialization...";
            std::string serial_str, compressed_str;
            try {
                serial_str.reserve(    std::pow(2.0, 29.0));
                compressed_str.reserve(std::pow(2.0, 26.0));
            } catch (...) {
                DebugLogger() << "Unable to preallocate full serialization buffers. Attempting serialization with dynamic buffer allocation.";
            }

            // wrap buffer string in iostream::stream to receive serialized data
            typedef boost::iostreams::back_insert_device<std::string> InsertDevice;
            InsertDevice serial_inserter(serial_str);
            boost::iostreams::stream<InsertDevice> s_sink(serial_inserter);

            // create archive with (preallocated) buffer...
            freeorion_xml_oarchive xoa(s_sink);
            // serialize main gamestate info
            xoa << BOOST_SERIALIZATION_NVP(player_save_game_data);
            xoa << BOOST_SERIALIZATION_NVP(empire_manager);
            xoa << BOOST_SERIALIZATION_NVP(species_manager);
            xoa << BOOST_SERIALIZATION_NVP(combat_log_manager);
            Serialize(xoa, universe);
            s_sink.flush();

            // wrap gamestate string in iostream::stream to extract serialized data
            typedef boost::iostreams::basic_array_source<char> SourceDevice;
            SourceDevice source(serial_str.data(), serial_str.size());
            boost::iostreams::stream<SourceDevice> s_source(source);

            // wrap compresed buffer string in iostream::streams to receive compressed string
            InsertDevice compressed_inserter(compressed_str);
            boost::iostreams::stream<InsertDevice> c_sink(compressed_inserter);

            // compression-filter gamestate into compressed string
            boost::iostreams::filtering_ostreambuf o;
            o.push(boost::iostreams::zlib_compressor());
            o.push(c_sink);
            boost::iostreams::copy(s_source, o);
            c_sink.flush();

            // write to save file: uncompressed header serialized data, with compressed main archive string at end...
            freeorion_xml_oarchive xoa2(ofs);
            // serialize uncompressed save header info
            xoa2 << BOOST_SERIALIZATION_NVP(save_preview_data);
            xoa2 << BOOST_SERIALIZATION_NVP(galaxy_setup_data);
            xoa2 << BOOST_SERIALIZATION_NVP(server_save_game_data);
            xoa2 << BOOST_SERIALIZATION_NVP(player_save_header_data);
            xoa2 << BOOST_SERIALIZATION_NVP(empire_save_game_data);
            // append compressed gamestate info
            xoa2 << BOOST_SERIALIZATION_NVP(compressed_str);
        }

    } catch (const std::exception& e) {
        ErrorLogger() << UserString("UNABLE_TO_WRITE_SAVE_FILE") << " SaveGame exception: " << ": " << e.what();
        throw e;
    }
    DebugLogger() << "SaveGame : Successfully wrote save file";
}
Exemple #9
0
void LoadGame(const std::string& filename, ServerSaveGameData& server_save_game_data,
              std::vector<PlayerSaveGameData>& player_save_game_data, Universe& universe,
              EmpireManager& empire_manager, SpeciesManager& species_manager,
              CombatLogManager& combat_log_manager, GalaxySetupData& galaxy_setup_data)
{
    //boost::this_thread::sleep_for(boost::chrono::seconds(1));

    ScopedTimer timer("LoadGame: " + filename, true);

    // player notifications
    if (ServerApp* server = ServerApp::GetApp())
        server->Networking().SendMessage(TurnProgressMessage(Message::LOADING_GAME));

    GetUniverse().EncodingEmpire() = ALL_EMPIRES;

    std::map<int, SaveGameEmpireData>   ignored_save_game_empire_data;
    SaveGamePreviewData                 ignored_save_preview_data;
    std::vector<PlayerSaveHeaderData>   ignored_player_save_header_data;

    empire_manager.Clear();
    universe.Clear();

    try {
        // set up input archive / stream for loading
        const fs::path path = FilenameToPath(filename);
        fs::ifstream ifs(path, std::ios_base::binary);
        if (!ifs)
            throw std::runtime_error(UNABLE_TO_OPEN_FILE);

        try {
            // first attempt binary deserialziation
            freeorion_bin_iarchive ia(ifs);
            DebugLogger() << "Reading binary iarchive";
            ia >> BOOST_SERIALIZATION_NVP(ignored_save_preview_data);
            ia >> BOOST_SERIALIZATION_NVP(galaxy_setup_data);
            ia >> BOOST_SERIALIZATION_NVP(server_save_game_data);
            ia >> BOOST_SERIALIZATION_NVP(ignored_player_save_header_data);
            ia >> BOOST_SERIALIZATION_NVP(ignored_save_game_empire_data);

            ia >> BOOST_SERIALIZATION_NVP(player_save_game_data);
            ia >> BOOST_SERIALIZATION_NVP(empire_manager);
            ia >> BOOST_SERIALIZATION_NVP(species_manager);
            ia >> BOOST_SERIALIZATION_NVP(combat_log_manager);
            Deserialize(ia, universe);
            DebugLogger() << "Done deserializing";
        } catch (...) {
            // if binary deserialization failed, try more-portable XML deserialization

            // reset to start of stream (attempted binary serialization will have consumed some input...)
            boost::iostreams::seek(ifs, 0, std::ios_base::beg);

            // allocate buffers for serialized gamestate
            DebugLogger() << "Allocating buffers for XML deserialization...";
            std::string serial_str, compressed_str;
            try {
                serial_str.reserve(    std::pow(2.0, 29.0));
                compressed_str.reserve(std::pow(2.0, 26.0));
            } catch (...) {
                DebugLogger() << "Unable to preallocate full deserialization buffers. Attempting deserialization with dynamic buffer allocation.";
            }

            // create archive with (preallocated) buffer...
            freeorion_xml_iarchive xia(ifs);
            // read from save file: uncompressed header serialized data, with compressed main archive string at end...
            // deserialize uncompressed save header info
            xia >> BOOST_SERIALIZATION_NVP(ignored_save_preview_data);
            xia >> BOOST_SERIALIZATION_NVP(galaxy_setup_data);
            xia >> BOOST_SERIALIZATION_NVP(server_save_game_data);
            xia >> BOOST_SERIALIZATION_NVP(ignored_player_save_header_data);
            xia >> BOOST_SERIALIZATION_NVP(ignored_save_game_empire_data);
            // extract compressed gamestate info
            xia >> BOOST_SERIALIZATION_NVP(compressed_str);

            // wrap compressed string in iostream::stream to extract compressed data
            typedef boost::iostreams::basic_array_source<char> SourceDevice;
            SourceDevice compressed_source(compressed_str.data(), compressed_str.size());
            boost::iostreams::stream<SourceDevice> c_source(compressed_source);

            // wrap uncompressed buffer string in iostream::stream to receive decompressed string
            typedef boost::iostreams::back_insert_device<std::string> InsertDevice;
            InsertDevice serial_inserter(serial_str);
            boost::iostreams::stream<InsertDevice> s_sink(serial_inserter);

            // set up filter to decompress data
            boost::iostreams::filtering_istreambuf i;
            i.push(boost::iostreams::zlib_decompressor());
            i.push(c_source);
            boost::iostreams::copy(i, s_sink);
            // The following line has been commented out because it caused an assertion in boost iostreams to fail
            // s_sink.flush();

            // wrap uncompressed buffer string in iostream::stream to extract decompressed string
            SourceDevice serial_source(serial_str.data(), serial_str.size());
            boost::iostreams::stream<SourceDevice> s_source(serial_source);

            // create archive with (preallocated) buffer...
            freeorion_xml_iarchive xia2(s_source);
            // deserialize main gamestate info
            xia2 >> BOOST_SERIALIZATION_NVP(player_save_game_data);
            xia2 >> BOOST_SERIALIZATION_NVP(empire_manager);
            xia2 >> BOOST_SERIALIZATION_NVP(species_manager);
            xia2 >> BOOST_SERIALIZATION_NVP(combat_log_manager);
            Deserialize(xia2, universe);
        }

    } catch (const std::exception& err) {
        ErrorLogger() << "LoadGame(...) failed!  Error: " << err.what();
        return;
    }
    DebugLogger() << "LoadGame : Successfully loaded save file";
}
int	ModuleCmd_List(	Tcl_Interp	*interp,
			int		 argc,
                   	char		*argv[])
{
    /**
     **  Get the list of loaded modules at first
     **/

    char	*loaded, *lmfiles;
    int		 i, count1, count2;
    char	*list[ MOD_BUFSIZE];
    char	*files[ MOD_BUFSIZE];
    char	*tmplist[ MOD_BUFSIZE], *s;
    int	  	 len;

#if WITH_DEBUGGING_MODULECMD
    ErrorLogger( NO_ERR_START, LOC, _proc_ModuleCmd_List, NULL);
#endif

    lmfiles = getLMFILES( interp);
    loaded = getenv( "LOADEDMODULES");
    
    if( !loaded || !*loaded) {
	if( sw_format & (SW_TERSE | SW_LONG | SW_HUMAN) )
	    fprintf(stderr, "No Modulefiles Currently Loaded.\n");
    } else {

	/**
	 **  Now tokenize it, form a list and print it out.
	 **/

	if( sw_format & SW_LONG ) {
	    fprintf( stderr, long_header);
	}
	if( sw_format & (SW_TERSE | SW_LONG | SW_HUMAN) )
	    fprintf( stderr, "Currently Loaded Modulefiles:\n");

	/**
	 **  LOADEDMODULES and _LMFILES_ should provide a list of loaded
	 **  modules and assigned files in the SAME ORDER
	 ** but double check, because if they aren't you will get a crash.
	 **/

	count1 = 1;
        for( list[ 0] = xstrtok( loaded, ":");
	     list[ count1] = xstrtok( NULL, ":");
	     count1++ );

	count2 = 1;
        for( files[ 0] = xstrtok( lmfiles, ":");
	     files[ count2] = xstrtok( NULL, ":");
	     count2++ );
	if (count1 != count2) {
	  ErrorLogger( ERR_ENVVAR, LOC, NULL);
	}
	  

	/**
	 **  We have to build a single list of files for each loaded entry
	 **  in order to be able to figure out the length of the directory
	 **  part
	 **/

	for( i=0; i<count1; i++) {

	    len = strlen( files[i]) - strlen( list[i]);
	    tmplist[i] = files[i];

	    /**
	     **  We have to source all relevant .modulerc and .version files
	     **  on the path
	     **/

	    s = files[i] + len;
	    while( s) {
		if( s = strchr( s, '/'))
		    *s = '\0';

		SourceRC( interp, files[i], modulerc_file);
		SourceVers( interp, files[i], list[i]);

		if( s)
		    *s++ = '/';
	    }

	    /** 
	     **  Print this guy
	     **/
	}
	print_aligned_files( interp, NULL, NULL, tmplist, count1, 1);
    }

    /**
     **  Return on success
     **/

#if WITH_DEBUGGING_MODULECMD
    ErrorLogger( NO_ERR_END, LOC, _proc_ModuleCmd_List, NULL);
#endif

    return( TCL_OK);

} /** End of 'ModuleCmd_List' **/
Exemple #11
0
int mainSetupAndRun() {
    try {
        int colour_depth = GetOptionsDB().Get<int>("color-depth");
        bool fullscreen = GetOptionsDB().Get<bool>("fullscreen");
        bool fake_mode_change = GetOptionsDB().Get<bool>("fake-mode-change");

        std::pair<int, int> width_height = HumanClientApp::GetWindowWidthHeight();
        int width(width_height.first), height(width_height.second);
        std::pair<int, int> left_top = HumanClientApp::GetWindowLeftTop();
        int left(left_top.first), top(left_top.second);

        int fullscreen_monitor_id = GetOptionsDB().Get<int>("fullscreen-monitor-id");

#ifdef FREEORION_WIN32
#  ifdef IDI_ICON1
        // set window icon to embedded application icon
        HWND hwnd;
        window->getCustomAttribute("WINDOW", &hwnd);
        HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
        SetClassLong (hwnd, GCL_HICON,
            (LONG)LoadIcon (hInst, MAKEINTRESOURCE (IDI_ICON1)));
#  endif
#endif

        parse::init();
        HumanClientApp app(width_height.first, width_height.second, true, "FreeOrion " + FreeOrionVersionString(), left, top, fullscreen, fake_mode_change);

        if (GetOptionsDB().Get<bool>("quickstart")) {
            // immediately start the server, establish network connections, and
            // go into a single player game, using default universe options (a
            // standard quickstart, without requiring the user to click the
            // quickstart button).
            app.NewSinglePlayerGame(true);  // acceptable to call before app()
        }

        std::string load_filename = GetOptionsDB().Get<std::string>("load");
        if (!load_filename.empty()) {
            // immediately start the server, establish network connections, and
            // go into a single player game, loading the indicated file
            // (without requiring the user to click the load button).
            app.LoadSinglePlayerGame(load_filename);  // acceptable to call before app()
        }

        // run rendering loop
        app();  // calls GUI::operator() which calls SDLGUI::Run() which starts rendering loop

    } catch (const HumanClientApp::CleanQuit&) {
        // do nothing
        std::cout << "mainSetupAndRun caught CleanQuit" << std::endl;
    } catch (const std::invalid_argument& e) {
        ErrorLogger() << "main() caught exception(std::invalid_argument): " << e.what();
        std::cerr << "main() caught exception(std::invalid_arg): " << e.what() << std::endl;
    } catch (const std::runtime_error& e) {
        ErrorLogger() << "main() caught exception(std::runtime_error): " << e.what();
        std::cerr << "main() caught exception(std::runtime_error): " << e.what() << std::endl;
    } catch (const  boost::io::format_error& e) {
        ErrorLogger() << "main() caught exception(boost::io::format_error): " << e.what();
        std::cerr << "main() caught exception(boost::io::format_error): " << e.what() << std::endl;
    } catch (const GG::ExceptionBase& e) {
        ErrorLogger() << "main() caught exception(" << e.type() << "): " << e.what();
        std::cerr << "main() caught exception(" << e.type() << "): " << e.what() << std::endl;
    } catch (const std::exception& e) {
        ErrorLogger() << "main() caught exception(std::exception): " << e.what();
        std::cerr << "main() caught exception(std::exception): " << e.what() << std::endl;
    } catch (...) {
        ErrorLogger() << "main() caught unknown exception.";
        std::cerr << "main() caught unknown exception." << std::endl;
    }

    return 0;
}
void PlayerListWnd::PlayerRightClicked(GG::ListBox::iterator it, const GG::Pt& pt, const GG::Flags<GG::ModKey>& modkeys) {
    // check that a valid player was clicked and that it wasn't this client's own player
    int clicked_player_id = PlayerInRow(it);
    if (clicked_player_id == Networking::INVALID_PLAYER_ID)
        return;
    const ClientApp* app = ClientApp::GetApp();
    if (!app) {
        ErrorLogger() << "PlayerListWnd::PlayerRightClicked couldn't get client app!";
        return;
    }
    int client_player_id = app->PlayerID();
    if (client_player_id == Networking::INVALID_PLAYER_ID)
        return;
    int client_empire_id = app->EmpireID();

    // get empire id of clicked player
    const std::map<int, PlayerInfo>& players = app->Players();
    std::map<int, PlayerInfo>::const_iterator clicked_player_it = players.find(clicked_player_id);
    if (clicked_player_it == players.end()) {
        ErrorLogger() << "PlayerListWnd::PlayerRightClicked couldn't find player with id " << clicked_player_id;
        return;
    }
    const PlayerInfo& clicked_player_info = clicked_player_it->second;
    int clicked_empire_id = clicked_player_info.empire_id;

    if (!GetEmpire(clicked_empire_id)) {
        ErrorLogger() << "PlayerListWnd::PlayerRightClicked tried to look up empire id "
                               << clicked_empire_id << " for player " << clicked_player_id
                               << " but couldn't find such an empire";
        return;
    }

    GG::MenuItem menu_contents;
    if (app->GetClientType() == Networking::CLIENT_TYPE_HUMAN_PLAYER) {
        // get diplomatic status between client and clicked empires
        DiplomaticStatus diplo_status = Empires().GetDiplomaticStatus(clicked_empire_id, client_empire_id);
        if (diplo_status == INVALID_DIPLOMATIC_STATUS && clicked_player_id != client_player_id) {
            ErrorLogger() << "PlayerListWnd::PlayerRightClicked found invalid diplomatic status between client and clicked empires.";
            return;
        }
        DiplomaticMessage existing_message = Empires().GetDiplomaticMessage(clicked_empire_id, client_empire_id);

        // create popup menu with diplomacy options in it
        if ( client_empire_id != ALL_EMPIRES) {
            if (diplo_status == DIPLO_WAR) {
                if (existing_message.GetType() == DiplomaticMessage::PEACE_PROPOSAL) {
                    // who sent message?
                    if (existing_message.SenderEmpireID() == client_empire_id)
                        menu_contents.next_level.push_back(GG::MenuItem(UserString("PEACE_PROPOSAL_CANEL"), 4, false, false));
                    else if (existing_message.SenderEmpireID() == clicked_empire_id)
                        menu_contents.next_level.push_back(GG::MenuItem(UserString("PEACE_ACCEPT"),         3, false, false));

                } else if (existing_message.GetType() == DiplomaticMessage::INVALID_DIPLOMATIC_MESSAGE_TYPE) {
                    menu_contents.next_level.push_back(GG::MenuItem(UserString("PEACE_PROPOSAL"),           2, false, false));
                }

            } else if (diplo_status == DIPLO_PEACE) {
                if (existing_message.GetType() == DiplomaticMessage::INVALID_DIPLOMATIC_MESSAGE_TYPE)
                    menu_contents.next_level.push_back(GG::MenuItem(UserString("WAR_DECLARATION"),          1, false, false));
            }
        }
    }

    menu_contents.next_level.push_back(GG::MenuItem(str(FlexibleFormat(UserString("ENC_LOOKUP")) % GetEmpire(clicked_empire_id)->Name()), 5, false, false));

    ClientNetworking& net = HumanClientApp::GetApp()->Networking();

    GG::PopupMenu popup(pt.x, pt.y, ClientUI::GetFont(), menu_contents, ClientUI::TextColor(),
                        ClientUI::WndOuterBorderColor(), ClientUI::WndColor(), ClientUI::EditHiliteColor());
    if (popup.Run()) {
        switch (popup.MenuID()) {
        case 1: {   // WAR_DECLARATION
            net.SendMessage(DiplomacyMessage(client_player_id, clicked_player_id,
                                             WarDeclarationDiplomaticMessage(client_empire_id, clicked_empire_id)));
            break;
        }
        case 2: {   // PEACE_PROPOSAL
            net.SendMessage(DiplomacyMessage(client_player_id, clicked_player_id,
                                             PeaceProposalDiplomaticMessage(client_empire_id, clicked_empire_id)));
            break;
        }
        case 3: {   // PEACE_ACCEPT
            net.SendMessage(DiplomacyMessage(client_player_id, clicked_player_id,
                                             AcceptDiplomaticMessage(client_empire_id, clicked_empire_id)));
            break;
        }
        case 4: {   // PEACE_PROPOSAL_CANEL
            net.SendMessage(DiplomacyMessage(client_player_id, clicked_player_id,
                                             CancelDiplomaticMessage(client_empire_id, clicked_empire_id)));
            break;
        }
        case 5: { // Pedia lookup
            ClientUI::GetClientUI()->ZoomToEmpire(clicked_empire_id);
            break;
        }
        default:
            break;
        }
    }
}
Exemple #13
0
/**
 * recursively creates dummy nodes between parent and child
 */
TechTreeLayout::Node::Node(Node* parent, Node* child, std::vector<Node*>& nodes) :
    m_depth(-1),
    m_row(-1),
    m_tech(),
    m_x(0),
    m_y(0),
    m_width(0),
    m_height(0),
    m_place_holder(true),
    m_children_rows(0),
    m_parents(),
    m_children(),
    m_primary_child(0),
    m_out_edges(),
    m_weight(LINE_CELL_HEIGHT)
{
    assert(parent != 0 && child != 0);
    // ensure passed in nodes are valid
    if (!parent)
        ErrorLogger() << "Node::Node passed null parent";
    if (!child)
        ErrorLogger() << "Node::Node passed null child";
    if (!parent || !child)
        return;

    //DebugLogger() << "Node::Node given parent " << parent
    //                       << " and child: " << child;

    //DebugLogger() << "Node::Node given parent with depth " << parent->m_depth
    //                       << "  and child with depth: " << child->m_depth;

    // ensure there is space to insert node between parent and child nodes
    if (child->m_depth <= parent->m_depth + 1) {
        ErrorLogger() << "no space to insert a dummy node!";
        m_depth = child->m_depth;
        return;
    }

    //DebugLogger() << "Node::Node adding dummy node: " << this
    //                       << "  between parent node tech: " << parent->m_tech
    //                       << "  and child node tech: " << child->m_tech;

    // add node to main node bookkeeping
    nodes.push_back(this);

    // copy parent/child connectivity
    m_depth = parent->m_depth + 1;
    m_tech = child->m_tech;
    m_parents.push_back(parent);
    m_children.push_back(child);
    m_primary_child = child;

    // update child's parents to point to this node instead of input parent
    std::vector<Node*>& child_parents = child->m_parents;
    for (unsigned int i = 0; i < child_parents.size(); ++i) {
        Node*& child_parent_ref = child_parents[i];
        if (child_parent_ref == parent)
            child_parent_ref = this;
    }

    // update parent's child node pointers to instead point to this node
    std::vector<Node*>& parent_children = parent->m_children;
    for (unsigned int i = 0; i < parent_children.size(); ++i) {
        Node*& parent_child_ref = parent_children[i];
        if (parent_child_ref == child)
            parent_child_ref = this;
    }
    if (parent->m_primary_child == child)
        parent->m_primary_child = this;
}
void AIClientApp::HandleMessage(const Message& msg) {
    //DebugLogger() << "AIClientApp::HandleMessage " << msg.Type();
    switch (msg.Type()) {
    case Message::ERROR_MSG: {
        ErrorLogger() << "AIClientApp::HandleMessage : Received ERROR message from server: " << msg.Text();
        break;
    }

    case Message::HOST_ID: {
        const std::string& text = msg.Text();
        int host_id = Networking::INVALID_PLAYER_ID;
        if (text.empty()) {
            ErrorLogger() << "AIClientApp::HandleMessage for HOST_ID : Got empty message text?!";
        } else {
            try {
                host_id = boost::lexical_cast<int>(text);
            } catch(const boost::bad_lexical_cast& ex) {
                ErrorLogger() << "AIClientApp::HandleMessage for HOST_ID : Couldn't parse message text \"" << text << "\": " << ex.what();
            }
        }
        m_networking->SetHostPlayerID(host_id);
        break;
    }

    case Message::JOIN_GAME: {
        if (PlayerID() == Networking::INVALID_PLAYER_ID) {
            DebugLogger() << "AIClientApp::HandleMessage : Received JOIN_GAME acknowledgement";
            try {
                int player_id;
                boost::uuids::uuid cookie; // ignore
                ExtractJoinAckMessageData(msg, player_id, cookie);
                m_networking->SetPlayerID(player_id);
            } catch(const boost::bad_lexical_cast& ex) {
                ErrorLogger() << "AIClientApp::HandleMessage for JOIN_GAME : Couldn't parse message text \"" << msg.Text() << "\": " << ex.what();
            }
        } else {
            ErrorLogger() << "AIClientApp::HandleMessage : Received erroneous JOIN_GAME acknowledgement when already in a game";
        }
        break;
    }

    case Message::GAME_START: {
        DebugLogger() << "AIClientApp::HandleMessage : Received GAME_START message; starting AI turn...";
        bool single_player_game;        // ignored
        bool loaded_game_data;
        bool ui_data_available;         // ignored
        SaveGameUIData ui_data;         // ignored
        bool state_string_available;    // ignored, as save_state_string is sent even if not set by ExtractMessageData
        std::string save_state_string;
        m_empire_status.clear();

        ExtractGameStartMessageData(msg,                     single_player_game,     m_empire_id,
                                    m_current_turn,          m_empires,              m_universe,
                                    GetSpeciesManager(),     GetCombatLogManager(),  GetSupplyManager(),
                                    m_player_info,           m_orders,               loaded_game_data,
                                    ui_data_available,       ui_data,                state_string_available,
                                    save_state_string,       m_galaxy_setup_data);

        DebugLogger() << "Extracted GameStart message for turn: " << m_current_turn << " with empire: " << m_empire_id;

        GetUniverse().InitializeSystemGraph(m_empire_id);

        DebugLogger() << "Message::GAME_START loaded_game_data: " << loaded_game_data;
        if (loaded_game_data) {
            TraceLogger() << "Message::GAME_START save_state_string: " << save_state_string;
            m_AI->ResumeLoadedGame(save_state_string);
            Orders().ApplyOrders();
        } else {
            DebugLogger() << "Message::GAME_START Starting New Game!";
            // % Distribution of aggression levels
            // Aggression   :  0   1   2   3   4   5   (0=Beginner, 5=Maniacal)
            //                __  __  __  __  __  __
            //Max 0         :100   0   0   0   0   0
            //Max 1         : 25  75   0   0   0   0
            //Max 2         :  0  25  75   0   0   0
            //Max 3         :  0   0  25  75   0   0
            //Max 4         :  0   0   0  25  75   0
            //Max 5         :  0   0   0   0  25  75

            // Optional aggression table, possibly for 0.4.4+?
            // Aggression   :  0   1   2   3   4   5   (0=Beginner, 5=Maniacal)
            //                __  __  __  __  __  __
            //Max 0         :100   0   0   0   0   0
            //Max 1         : 25  75   0   0   0   0
            //Max 2         :  8  17  75   0   0   0
            //Max 3         :  0   8  17  75   0   0
            //Max 4         :  0   0   8  17  75   0
            //Max 5         :  0   0   0   8  17  75

            const std::string g_seed = GetGalaxySetupData().m_seed;
            const std::string emp_name = GetEmpire(m_empire_id)->Name();
            unsigned int my_seed = 0;

            try {
                // generate consistent my_seed values from galaxy seed & empire name.
                boost::hash<std::string> string_hash;
                std::size_t h = string_hash(g_seed);
                my_seed = 3 * static_cast<unsigned int>(h) * static_cast<unsigned int>(string_hash(emp_name));
                DebugLogger() << "Message::GAME_START getting " << emp_name << " AI aggression, RNG Seed: " << my_seed;
            } catch (...) {
                DebugLogger() << "Message::GAME_START getting " << emp_name << " AI aggression, could not initialise RNG.";
            }

            int rand_num = 0;
            int this_aggr = m_max_aggression;

            if (this_aggr > 0  && my_seed > 0) {
                Seed(my_seed);
                rand_num = RandSmallInt(0, 99);
                // if it's in the top 25% then decrease aggression.
                if (rand_num > 74) this_aggr--;
                // Leaving the following as commented out code for now. Possibly for 0.4.4+?
                // in the top 8% ? decrease aggression again, unless it's already as low as it gets.
                // if (rand_num > 91 && this_aggr > 0) this_aggr--;
            }

            DebugLogger() << "Message::GAME_START setting AI aggression as " << this_aggr << " (from rnd " << rand_num << "; max aggression " << m_max_aggression << ")";

            m_AI->SetAggression(this_aggr);
            m_AI->StartNewGame();
        }
        m_AI->GenerateOrders();
        break;
    }

    case Message::SAVE_GAME_COMPLETE:
        break;

    case Message::TURN_UPDATE: {
        //DebugLogger() << "AIClientApp::HandleMessage : extracting turn update message data";
        ExtractTurnUpdateMessageData(msg,                     m_empire_id,        m_current_turn,
                                     m_empires,               m_universe,         GetSpeciesManager(),
                                     GetCombatLogManager(),   GetSupplyManager(), m_player_info);
        //DebugLogger() << "AIClientApp::HandleMessage : generating orders";
        GetUniverse().InitializeSystemGraph(m_empire_id);
        m_AI->GenerateOrders();
        //DebugLogger() << "AIClientApp::HandleMessage : done handling turn update message";
        break;
    }

    case Message::TURN_PARTIAL_UPDATE:
        ExtractTurnPartialUpdateMessageData(msg, m_empire_id, m_universe);
        break;

    case Message::TURN_PROGRESS: {
        Message::TurnProgressPhase phase_id;
        ExtractTurnProgressMessageData(msg, phase_id);
        ClientApp::HandleTurnPhaseUpdate(phase_id);
        break;
    }

    case Message::PLAYER_STATUS:
        break;

    case Message::END_GAME: {
        DebugLogger() << "Message::END_GAME : Exiting";
        DebugLogger() << "Acknowledge server shutdown message.";
        Networking().SendMessage(AIEndGameAcknowledgeMessage());
        ExitApp(0);
        break;
    }

    case Message::PLAYER_CHAT: {
        std::string data;
        int player_id;
        boost::posix_time::ptime timestamp;
        ExtractServerPlayerChatMessageData(msg, player_id, timestamp, data);
        m_AI->HandleChatMessage(player_id, data);
        break;
    }

    case Message::DIPLOMACY: {
        DiplomaticMessage diplo_message;
        ExtractDiplomacyMessageData(msg, diplo_message);
        m_AI->HandleDiplomaticMessage(diplo_message);
        break;
    }

    case Message::DIPLOMATIC_STATUS: {
        DiplomaticStatusUpdateInfo diplo_update;
        ExtractDiplomaticStatusMessageData(msg, diplo_update);
        m_AI->HandleDiplomaticStatusUpdate(diplo_update);
        break;
    }

    case Message::LOGGER_CONFIG: {
         std::set<std::tuple<std::string, std::string, LogLevel>> options;
         ExtractLoggerConfigMessageData(msg, options);

         SetLoggerThresholds(options);
         break;
    }

    case Message::CHECKSUM: {
        TraceLogger() << "(AIClientApp) CheckSum.";
        VerifyCheckSum(msg);
        break;
    }

    default: {
        ErrorLogger() << "AIClientApp::HandleMessage : Received unknown Message type code " << msg.Type();
        break;
    }
    }
    //DebugLogger() << "AIClientApp::HandleMessage done";
}
int	cmdUname(	ClientData	 client_data,
	  		Tcl_Interp	*interp,
	  		int		 argc,
	  		CONST84 char	*argv[])
{
    int  length;
#ifdef PHOSTNAME
#ifndef HAVE_GETHOSTNAME
    FILE* hname;
#endif
#endif

#if WITH_DEBUGGING_CALLBACK
    ErrorLogger( NO_ERR_START, LOC, _proc_cmdUname, NULL);
#endif

    /**
     **  Parameter check. One parameter should be given providing a selector
     **  do differ between:
     **/

    if( argc != 2) {
	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "member", NULL))
	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
    }

#ifdef HAVE_UNAME

    /**
     **  Proceed the system call
     **/

    if( !namestruct_init && uname( &namestruct) < 0) {
	if( OK != ErrorLogger( ERR_UNAME, LOC, NULL))
	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
    }

#else /* not HAVE_UNAME */

    /**
     **  If we do not have the uname system call, fixed values defined 
     **  at compile time will be returned. The only differenc is the
     **  nodename, which may be seeked for using 'gethostname' or the
     **  PHOSTNAME file.
     **/

#ifdef HAVE_GETHOSTNAME

    if( -1 == gethostname( namestruct.nodename, NAMELEN)) 
	if( OK != ErrorLogger( ERR_GETHOSTNAME, LOC, NULL))
	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/

#else /* not HAVE_GETHOSTNAME */

#ifdef PHOSTNAME

    if( NULL == (hname = popen( PHOSTNAME, "r"))) {
	if( OK != ErrorLogger( ERR_POPEN, LOC, PHOSTNAME, "reading", NULL))
	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
    }

    fgets( namestruct.nodename, NAMELEN, hname);
    namestruct.nodename[ strlen( namestruct.nodename)-1] = '\0';

    if( -1 == pclose( hname))
	if( OK != ErrorLogger( ERR_PCLOSE, LOC, PHOSTNAME, NULL))
	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/

#endif /* not PHOSTNAME */
#endif /* not HAVE_GETHOSTNAME */

#endif /* not HAVE_UNAME */
 
    /**
     **  Set up the domain name
     **/

#ifdef HAVE_GETDOMAINNAME
    if( !namestruct_init)
        if( -1 == getdomainname( domain, DOMAINLEN))
	    if( OK != ErrorLogger( ERR_GETDOMAINNAME, LOC, NULL))
		return( TCL_ERROR);	/** -------- EXIT (FAILURE) -------> **/
#endif

    /**
     **  Now the name structure surely IS initialized
     **/

    namestruct_init = 1;

    /**
     **  Return the selected value
     **/

    length = strlen( argv[1]);

    if( !strncmp( argv[1], "sysname", length)) {
        Tcl_SetResult( interp, namestruct.sysname, TCL_VOLATILE);
    } else if( !strncmp( argv[1], "nodename", length)) {
        Tcl_SetResult( interp, namestruct.nodename, TCL_VOLATILE);
    } else if( !strncmp( argv[1], "release", length)) {
        Tcl_SetResult( interp, namestruct.release, TCL_VOLATILE);
    } else if( !strncmp( argv[1], "version", length)) {
        Tcl_SetResult( interp, namestruct.version, TCL_VOLATILE);
    } else if( !strncmp( argv[1], "machine", length)) {
        Tcl_SetResult( interp, namestruct.machine, TCL_VOLATILE);
    } else if( !strncmp( argv[1], "domain", length)) {
        Tcl_SetResult( interp, domain, TCL_VOLATILE);
    } else {
	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "{sysname|nodename|"
	    "release|version|machine|domain}", NULL))
	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
    }

#if WITH_DEBUGGING_CALLBACK
    ErrorLogger( NO_ERR_END, LOC, _proc_cmdUname, NULL);
#endif

    return( TCL_OK);			/** -------- EXIT (SUCCESS) -------> **/

} /** End of 'cmdUname' **/
Exemple #16
0
int main(int argc, char* argv[]) {
    InitDirs(argv[0]);
    std::vector<std::string> args;
    for (int i = 0; i < argc; ++i)
        args.push_back(argv[i]);

#else
int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) {
    // copy UTF-16 command line arguments to UTF-8 vector
    std::vector<std::string> args;
    for (int i = 0; i < argc; ++i) {
        std::wstring argi16(argv[i]);
        std::string argi8;
        utf8::utf16to8(argi16.begin(), argi16.end(), std::back_inserter(argi8));
        args.push_back(argi8);
    }
    InitDirs((args.empty() ? "" : *args.begin()));
#endif

    try {
        GetOptionsDB().AddFlag('h', "help", "Print this help message.");

        // read config.xml and set options entries from it, if present
        XMLDoc doc;
        {
            boost::filesystem::ifstream ifs(GetConfigPath());
            if (ifs) {
                doc.ReadDoc(ifs);
                GetOptionsDB().SetFromXML(doc);
            }

            try {
                boost::filesystem::ifstream pifs(GetPersistentConfigPath());
                if (pifs) {
                    doc.ReadDoc(pifs);
                    GetOptionsDB().SetFromXML(doc);
                }
            } catch (const std::exception&) {
                ErrorLogger() << "main() unable to read persistent option config file: " 
                              << GetPersistentConfigPath() << std::endl;
            }
        }

        GetOptionsDB().SetFromCommandLine(args);

        if (GetOptionsDB().Get<bool>("help")) {
            GetOptionsDB().GetUsage(std::cerr);
            return 0;
        }

        parse::init();

        ServerApp g_app;
        g_app(); // Calls ServerApp::Run() to run app (intialization and main process loop)

    } catch (const std::invalid_argument& e) {
        ErrorLogger() << "main() caught exception(std::invalid_arg): " << e.what();
        std::cerr << "main() caught exception(std::invalid_arg): " << e.what() << std::endl;
        return 1;
    } catch (const std::runtime_error& e) {
        ErrorLogger() << "main() caught exception(std::runtime_error): " << e.what();
        std::cerr << "main() caught exception(std::runtime_error): " << e.what() << std::endl;
        return 1;
    } catch (const std::exception& e) {
        ErrorLogger() << "main() caught exception(std::exception): " << e.what();
        std::cerr << "main() caught exception(std::exception): " << e.what() << std::endl;
        return 1;
    } catch (...) {
        ErrorLogger() << "main() caught unknown exception.";
        std::cerr << "main() caught unknown exception." << std::endl;
        return 1;
    }

    return 0;
}
Exemple #17
0
static	int	PerModuleHelp(	Tcl_Interp	*interp,
		    		int         	 argc,
		    		char		*argv[])
{
    Tcl_Interp	*help_interp;
    Tcl_DString	 cmdbuf;
    int		 i,
    		 result;
    char	 modulefile[ MOD_BUFSIZE];
    char	 modulename[ MOD_BUFSIZE];
    
    /**
     **  Initialize the command buffer
     **/
    Tcl_DStringInit( &cmdbuf);
    g_flags |= M_HELP;

    /**
     **  Handle each passed module file. Create a Tcl interpreter for each 
     **  module file to be handled
     **/
    for(i=0; i<argc; i++) {

	help_interp = EM_CreateInterp();
	if( TCL_OK != (result = Module_Init( help_interp))) {
	    EM_DeleteInterp( help_interp);
	    result = TCL_ERROR;
	    break;
	}

	/**
	 **  locate the filename related to the passed module
	 **/

	if( Locate_ModuleFile( help_interp, argv[i], modulename, modulefile)) {
	    if( OK != ErrorLogger( ERR_LOCATE, LOC, argv[i], NULL)) {
		g_retval = 1;  
		continue;
	}
	    EM_DeleteInterp( help_interp);
	}

	/**
	 **  Now print the module specific help ...
	 **/

        g_current_module = modulename;
	fprintf( stderr,
		 "\n----------- %s '%s' %.*s-------\n\n", 
		 _("Module Specific Help for"),
		 g_current_module, (int)(20-strlen( g_current_module)),
		 "--------------------");
	result = CallModuleProcedure( help_interp, &cmdbuf, modulefile,
	    "ModulesHelp", 1);

	/**
	 **  If there hasn't been any help ...
	 **/

	if( result == TCL_ERROR)
	    fprintf( stderr, "\t*** %s %s ***\n", 
		_("No Module Specific Help for"), 
		g_current_module);

	/**
	 **  Finally clear up the Tcl interpreter and handle the next module
	 **/

	EM_DeleteInterp( help_interp);
    }

    /**
     **  Free the used command buffer and return on success
     **/

    g_flags &= ~M_HELP;
    Tcl_DStringFree(&cmdbuf);

    return( TCL_OK);

} /** End of 'PerModuleHelp' **/
Exemple #18
0
void ShipDesignOrder::ExecuteImpl() const {
    ValidateEmpireID();

    Universe& universe = GetUniverse();

    Empire* empire = GetEmpire(EmpireID());
    if (m_delete_design_from_empire) {
        // player is ordering empire to forget about a particular design
        if (!empire->ShipDesignKept(m_design_id)) {
            ErrorLogger() << "Tried to remove a ShipDesign that the empire wasn't remembering";
            return;
        }
        empire->RemoveShipDesign(m_design_id);

    } else if (m_create_new_design) {
        // check if a design with this ID already exists
        if (universe.GetShipDesign(m_design_id)) {
            ErrorLogger() << "Tried to create a new ShipDesign with an id of an already-existing ShipDesign";
            return;
        }
        ShipDesign* new_ship_design = new ShipDesign(m_name, m_description,
                                                     m_designed_on_turn, EmpireID(), m_hull, m_parts,
                                                     m_icon, m_3D_model, m_name_desc_in_stringtable,
                                                     m_is_monster);

        universe.InsertShipDesignID(new_ship_design, m_design_id);
        universe.SetEmpireKnowledgeOfShipDesign(m_design_id, EmpireID());
        empire->AddShipDesign(m_design_id);

    } else if (m_update_name_or_description) {
        // player is ordering empire to rename a design
        const std::set<int>& empire_known_design_ids = universe.EmpireKnownShipDesignIDs(EmpireID());
        std::set<int>::iterator design_it = empire_known_design_ids.find(m_design_id);
        if (design_it == empire_known_design_ids.end()) {
            ErrorLogger() << "Tried to rename/redescribe a ShipDesign that this empire hasn't seen";
            return;
        }
        const ShipDesign* design = GetShipDesign(*design_it);
        if (!design) {
            ErrorLogger() << "Tried to rename/redescribe a ShipDesign that doesn't exist (but this empire has seen it)!";
            return;
        }
        if (design->DesignedByEmpire() != EmpireID()) {
            ErrorLogger() << "Tried to rename/redescribe a ShipDesign that isn't owned by this empire!";
            return;
        }
        GetUniverse().RenameShipDesign(m_design_id, m_name, m_description);

    } else if (m_move_design) {
        //Move an existing design from its current location to just before the after_design
        if (!empire->ShipDesignKept(m_design_id)) {
            ErrorLogger() << "Tried to move a ShipDesign that the empire wasn't remembering";
            return;
        }
        if (m_design_id == m_design_id_after)
            return;

        empire->RemoveShipDesign(m_design_id);
        empire->AddShipDesign(m_design_id, m_design_id_after);
        DebugLogger() << "Move Ship Design " << m_design_id << " to before " << m_design_id_after;
    } else {
        // player is ordering empire to retain a particular design, so that is can
        // be used to construct ships by that empire.

        // TODO: consider removing this order, so that an empire needs to use
        // espionage or trade to gain access to a ship design made by another
        // player

        // check if empire is already remembering the design
        if (empire->ShipDesignKept(m_design_id)) {
            ErrorLogger() << "Tried to remember a ShipDesign that was already being remembered";
            return;
        }

        // check if the empire can see any objects that have this design (thus enabling it to be copied)
        const std::set<int>& empire_known_design_ids = universe.EmpireKnownShipDesignIDs(EmpireID());
        if (empire_known_design_ids.find(m_design_id) != empire_known_design_ids.end()) {
            empire->AddShipDesign(m_design_id);
        } else {
            ErrorLogger() << "Tried to remember a ShipDesign that this empire hasn't seen";
            return;
        }

    }
}
static	int _getopt_internal(	int			 argc,
				char *const	 	*argv,
				const char	 	*optstring,
				const struct option	*longopts,
				int			*longind,
				int			 long_only)
{
    optarg = NULL;

#ifdef _MODULES_DEF_H
#  if WITH_DEBUGGING_INIT
    ErrorLogger( NO_ERR_START, LOC, _proc_getopt_internal, NULL);
#  endif
#endif

    /**
     **  Initialization
     **/

    if( optind == 0) {
	optstring = _getopt_initialize( optstring);
	optind = 1;		/** Don't scan ARGV[0], the program name.    **/
    }

    if( nextchar == NULL || *nextchar == '\0') {

	/**
	 **  Advance to the next ARGV-element.
	 **/

	if( ordering == PERMUTE) {

	    /**
	     **  If we have just processed some options following some non-
	     **  options, exchange them so that the options come first. 
	     **/

	    if( first_nonopt != last_nonopt && last_nonopt != optind)
		exchange( (char **) argv);
	    else if( last_nonopt != optind)
		first_nonopt = optind;

	    /**
	     **  Skip any additional non-options and extend the range of
	     **  non-options previously skipped. 
	     **/

	    while( optind < argc &&
		  ( argv[optind][0] != '-' || argv[optind][1] == '\0'))
		optind++;

	    last_nonopt = optind;
	}

	/**
	 **  The special ARGV-element `--' means premature end of options.
	 **  Skip it like a null option, then exchange with previous non-
	 **  options **  as if it were an option, then skip everything else
	 **  like a non-option. 
	 **/

	if( optind != argc && !strcmp( argv[optind], "--")) {

	    optind++;

	    if( first_nonopt != last_nonopt && last_nonopt != optind)
		exchange((char **) argv);
	    else if( first_nonopt == last_nonopt)
		first_nonopt = optind;

	    last_nonopt = argc;

	    optind = argc;
	}

	/**
	 **  If we have done all the ARGV-elements, stop the scan and back
	 **  over any non-options that we skipped and permuted. 
	 **/

	if( optind == argc) {

	    /**
	     **  Set the next-arg-index to point at the non-options that we
	     **  previously skipped, so the caller will digest them. 
	     **/

	    if( first_nonopt != last_nonopt)
		optind = first_nonopt;

	    return( EOF);
	}

	/**
	 **  If we have come to a non-option and did not permute it,
	 **  either stop the scan or describe it to the caller and pass it by. 
	 **/

	if( argv[optind][0] != '-' || argv[optind][1] == '\0') {

	    if( ordering == REQUIRE_ORDER)
		return EOF;
	    optarg = argv[optind++];

	    return( 1);
	}

	/**
	 **  We have found another option-ARGV-element. 
	 **  Skip the initial punctuation. 
	 **/

	nextchar =( argv[optind] + 1 +
	   ( longopts != NULL && argv[optind][1] == '-'));
    }

    /**
     **    Decode the current option-ARGV-element. 
     **/

    /**
     **  Check whether the ARGV-element is a long option.
     **
     **  If long_only and the ARGV-element has the form "-f", where f is
     **  a valid short option, don't consider it an abbreviated form of
     **  a long option that starts with f.  Otherwise there would be no
     **  way to give the -f short option.
     **
     **  On the other hand, if there's a long option "fubar" and
     **  the ARGV-element is "-fu", do consider that an abbreviation of
     **  the long option, just like "--fu", and not "-f" with arg "u".
     **
     **  This distinction seems to be the most useful approach. 
     **/

    if( longopts != NULL &&( argv[optind][1] == '-'     ||
       (  long_only &&
	 (  argv[optind][2] || !my_index (optstring, argv[optind][1]))))) {

	char *nameend;
	const struct option *p;
	const struct option *pfound = NULL;
	int exact = 0;
	int ambig = 0;
	int indfound;
	int option_index;

	/**
	 **  Skip the remaining characters of the long option upt to its
	 **  names end( End of the option itsself or the '=' sign)
	 **/

	for( nameend = nextchar; *nameend && *nameend != '='; nameend++);

	/**
	 **  Test all long options for either exact match or abbreviated
	 **  matches.
	 **/

	for( p = longopts, option_index = 0; p->name; p++, option_index++) {
	    if( !strncmp( p->name, nextchar, nameend - nextchar)) {

		if( nameend - nextchar == strlen( p->name)) {

		    /**
		     ** Exact match found. 
		     **/

		    pfound = p;
		    indfound = option_index;
		    exact = 1;
		    break;

		} else if( pfound == NULL) {

		    /**
		     **  First nonexact match found.
		     **/

		    pfound = p;
		    indfound = option_index;

		} else

		    /**
		     **  Second or later nonexact match found. 
		     **/

		    ambig = 1;

	    } /** if( !strncmp) **/
	} /** for **/

	/**
	 **  Print an error message for ambigious abbreviations and exit
	 **  on error
	 **/

	if( ambig && !exact) {

	    if( opterr)
#ifdef	_MODULES_DEF_H
		ErrorLogger( ERR_OPT_AMBIG, LOC, argv[optind], NULL);
#else
		fprintf( stderr, _("%s: option `%s' is ambiguous\n"),
		    argv[0], argv[optind]);
#endif

	    nextchar += strlen( nextchar);
	    optind++;
	    return( '?');
	}

	/**
	 **  Longname found ?
	 **/

	if( pfound != NULL) {

	    option_index = indfound;
	    optind++;

	    /**
	     **  *nameend is != NULL if there is a value specified for
	     **  the option: '--option=value' -> *nameend = '='
	     **/

	    if( *nameend) {

		/**
		 **  Don't test has_arg with >, because some C compilers don't
		 **  allow it to be used on enums. 
		 **/

		if( pfound->has_arg)
		    optarg = nameend + 1;

		else {
		    	  
		    if( opterr)

			/**
			 **  ERROR: --option w/o argument
			 **/

			if( argv[optind - 1][1] == '-')
#ifdef	_MODULES_DEF_H
			    ErrorLogger( ERR_OPT_NOARG, LOC, pfound->name, NULL);
#else
			    fprintf( stderr,
				_("%s: option `--%s' doesn't allow an argument\n"),
				argv[0], pfound->name);
#endif

			/**
			 **  ERROR: +option or -option w/o argument
			 **/

			else {
#ifdef	_MODULES_DEF_H
			    char buffer[ BUFSIZ];
			    sprintf( buffer, "%c%s", argv[optind - 1][0], pfound->name);
			    ErrorLogger( ERR_OPT_NOARG, LOC, buffer, NULL);
#else
			    fprintf( stderr,
				_("%s: option `%c%s' doesn't allow an argument\n"),
				argv[0], argv[optind - 1][0], pfound->name);
#endif
			}

		    nextchar += strlen( nextchar);
		    return( '?');
		}

	    /**
	     **  Options with arguments
	     **/

	    } else if( pfound->has_arg == 1) {
Exemple #20
0
void NewFleetOrder::ExecuteImpl() const {
    ValidateEmpireID();

    if (m_system_id == INVALID_OBJECT_ID) {
        ErrorLogger() << "Empire attempted to create a new fleet outside a system";
        return;
    }
    TemporaryPtr<System> system = GetSystem(m_system_id);
    if (!system) {
        ErrorLogger() << "Empire attempted to create a new fleet in a nonexistant system";
        return;
    }

    if (m_fleet_names.empty())
        return;
    if (m_fleet_names.size() != m_fleet_ids.size()
        || m_fleet_names.size() != m_ship_id_groups.size()
        || m_fleet_names.size() != m_aggressives.size())
    {
        ErrorLogger() << "NewFleetOrder has inconsistent data container sizes...";
        return;
    }

    GetUniverse().InhibitUniverseObjectSignals(true);
    std::vector<TemporaryPtr<Fleet> > created_fleets;
    created_fleets.reserve(m_fleet_names.size());


    // create fleet for each group of ships
    for (int i = 0; i < static_cast<int>(m_fleet_names.size()); ++i) {
        const std::string&      fleet_name =    m_fleet_names[i];
        int                     fleet_id =      m_fleet_ids[i];
        const std::vector<int>& ship_ids =      m_ship_id_groups[i];
        bool                    aggressive =    m_aggressives[i];

        if (ship_ids.empty())
            continue;   // nothing to do...

        // validate specified ships
        std::vector<TemporaryPtr<Ship> >    validated_ships;
        std::vector<int>                    validated_ships_ids;
        for (unsigned int i = 0; i < ship_ids.size(); ++i) {
            // verify that empire is not trying to take ships from somebody else's fleet
            TemporaryPtr<Ship> ship = GetShip(ship_ids[i]);
            if (!ship) {
                ErrorLogger() << "Empire attempted to create a new fleet with an invalid ship";
                continue;
            }
            if (!ship->OwnedBy(EmpireID())) {
                ErrorLogger() << "Empire attempted to create a new fleet with ships from another's fleet.";
                continue;
            }
            if (ship->SystemID() != m_system_id) {
                ErrorLogger() << "Empire attempted to make a new fleet from ship in the wrong system";
                continue;
            }
            validated_ships.push_back(ship);
            validated_ships_ids.push_back(ship->ID());
        }
        if (validated_ships.empty())
            continue;

        // create fleet
        TemporaryPtr<Fleet> fleet = GetUniverse().CreateFleet(fleet_name, system->X(), system->Y(),
                                                              EmpireID(), fleet_id);
        fleet->GetMeter(METER_STEALTH)->SetCurrent(Meter::LARGE_VALUE);
        fleet->SetAggressive(aggressive);

        // an ID is provided to ensure consistancy between server and client universes
        GetUniverse().SetEmpireObjectVisibility(EmpireID(), fleet->ID(), VIS_FULL_VISIBILITY);

        system->Insert(fleet);

        // new fleet will get same m_arrival_starlane as fleet of the first ship in the list.
        TemporaryPtr<Ship> firstShip = validated_ships[0];
        TemporaryPtr<Fleet> firstFleet = GetFleet(firstShip->FleetID());
        if (firstFleet)
            fleet->SetArrivalStarlane(firstFleet->ArrivalStarlane());

        // remove ships from old fleet(s) and add to new
        for (std::vector<TemporaryPtr<Ship> >::iterator ship_it = validated_ships.begin();
             ship_it != validated_ships.end(); ++ship_it)
        {
            TemporaryPtr<Ship> ship = *ship_it;
            if (TemporaryPtr<Fleet> old_fleet = GetFleet(ship->FleetID()))
                old_fleet->RemoveShip(ship->ID());
            ship->SetFleetID(fleet->ID());
        }
        fleet->AddShips(validated_ships_ids);

        created_fleets.push_back(fleet);
    }

    GetUniverse().InhibitUniverseObjectSignals(false);

    system->FleetsInsertedSignal(created_fleets);
    system->StateChangedSignal();
}
Exemple #21
0
bool Planet::Colonize(int empire_id, const std::string& species_name, double population) {
    const Species* species = 0;

    // if desired pop > 0, we want a colony, not an outpost, so we need to do some checks
    if (population > 0.0) {
        // check if specified species exists and get reference
        species = GetSpecies(species_name);
        if (!species) {
            ErrorLogger() << "Planet::Colonize couldn't get species already on planet with name: " << species_name;
            return false;
        }
        // check if specified species can colonize this planet
        if (EnvironmentForSpecies(species_name) < PE_HOSTILE) {
            ErrorLogger() << "Planet::Colonize: can't colonize planet already populated by species " << species_name;
            return false;
        }
    }

    // reset the planet to unowned/unpopulated
    if (!OwnedBy(empire_id)) {
        Reset();
    } else {
        PopCenter::Reset();
        for (std::set<int>::const_iterator it = m_buildings.begin(); it != m_buildings.end(); ++it)
            if (TemporaryPtr<Building> building = GetBuilding(*it))
                building->Reset();
        m_just_conquered = false;
        m_is_about_to_be_colonized = false;
        m_is_about_to_be_invaded = false;
        m_is_about_to_be_bombarded = false;
        SetOwner(ALL_EMPIRES);
    }

    // if desired pop > 0, we want a colony, not an outpost, so we have to set the colony species
    if (population > 0.0)
        SetSpecies(species_name);

    // find a default focus. use first defined available focus.
    // AvailableFoci function should return a vector of all names of
    // available foci.
    std::vector<std::string> available_foci = AvailableFoci();
    if (species && !available_foci.empty()) {
        bool found_preference = false;
        for (std::vector<std::string>::const_iterator it = available_foci.begin();
             it != available_foci.end(); ++it)
        {
            if (!it->empty() && *it == species->PreferredFocus()) {
                SetFocus(*it);
                found_preference = true;
                break;
            }
        }

        if (!found_preference)
            SetFocus(*available_foci.begin());
    } else {
        DebugLogger() << "Planet::Colonize unable to find a focus to set for species " << species_name;
    }

    // set colony population
    GetMeter(METER_POPULATION)->SetCurrent(population);
    GetMeter(METER_TARGET_POPULATION)->SetCurrent(population);
    BackPropagateMeters();


    // set specified empire as owner
    SetOwner(empire_id);

    // if there are buildings on the planet, set the specified empire as their owner too
    std::vector<TemporaryPtr<Building> > buildings = Objects().FindObjects<Building>(BuildingIDs());
    for (std::vector<TemporaryPtr<Building> >::iterator building_it = buildings.begin();
         building_it != buildings.end(); ++building_it)
    { (*building_it)->SetOwner(empire_id); }

    return true;
}
Exemple #22
0
void FleetMoveOrder::ExecuteImpl() const {
    ValidateEmpireID();

    TemporaryPtr<Fleet> fleet = GetFleet(FleetID());
    if (!fleet) {
        ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet with id " << FleetID() << " to move, but no such fleet exists";
        return;
    }

    TemporaryPtr<const System> destination_system = GetEmpireKnownSystem(DestinationSystemID(), EmpireID());
    if (!destination_system) {
        ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet to move to system with id " << DestinationSystemID() << " but no such system is known to that empire";
        return;
    }

    // reject empty routes
    if (m_route.empty()) {
        ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet to move on empty route";
        return;
    }

    // verify that empire specified in order owns specified fleet
    if (!fleet->OwnedBy(EmpireID()) ) {
        ErrorLogger() << "Empire with id " << EmpireID() << " order to move but does not own fleet with id " << FleetID();
        return;
    }


    // verify fleet route first system
    int fleet_sys_id = fleet->SystemID();
    if (!m_append || fleet->TravelRoute().empty()) {
        if (fleet_sys_id != INVALID_OBJECT_ID) {
            // fleet is in a system.  Its move path should also start from that system.
            if (fleet_sys_id != m_start_system) {
                ErrorLogger() << "Empire with id " << EmpireID()
                              << " ordered a fleet to move from a system with id " << m_start_system
                              << " that it is not at.  Fleet is located at system with id " << fleet_sys_id;
                return;
            }
        } else {
            // fleet is not in a system.  Its move path should start from the next system it is moving to.
            int next_system = fleet->NextSystemID();
            if (next_system != m_start_system) {
                ErrorLogger() << "Empire with id " << EmpireID()
                              << " ordered a fleet to move starting from a system with id " << m_start_system
                              << ", but the fleet's next destination is system with id " << next_system;
                return;
            }
        }
    } else {
        // We should append and there is something to append to
        int last_system = fleet->TravelRoute().back();
        if (last_system != m_start_system) {
            ErrorLogger() << "Empire with id " << EmpireID()
                          << " ordered a fleet to continue from system with id " << m_start_system
                          << ", but the fleet's current route won't lead there, it leads to system " << last_system;
            return;
        }
    }


    // convert list of ids to list of System
    std::list<int> route_list;

    if(m_append && !fleet->TravelRoute().empty()){
        route_list = fleet->TravelRoute();
        route_list.erase(--route_list.end());// Remove the last one since it is the first one of the other
    }

    std::copy(m_route.begin(), m_route.end(), std::back_inserter(route_list));


    // validate route.  Only allow travel between systems connected in series by starlanes known to this fleet's owner.

    // check destination validity: disallow movement that's out of range
    std::pair<int, int> eta = fleet->ETA(fleet->MovePath(route_list));
    if (eta.first == Fleet::ETA_NEVER || eta.first == Fleet::ETA_OUT_OF_RANGE) {
        DebugLogger() << "FleetMoveOrder::ExecuteImpl rejected out of range move order";
        return;
    }

    std::string waypoints;
    for (std::list<int>::iterator it = route_list.begin(); it != route_list.end(); ++it) {
        waypoints += std::string(" ") + boost::lexical_cast<std::string>(*it);
    }
    DebugLogger() << "FleetMoveOrder::ExecuteImpl Setting route of fleet " << fleet->ID() << " to " << waypoints;

    fleet->SetRoute(route_list);
}
Exemple #23
0
bool ShipDesign::ProductionLocation(int empire_id, int location_id) const {
    TemporaryPtr<const UniverseObject> location = GetUniverseObject(location_id);
    if (!location)
        return false;

    // currently ships can only be built at planets, and by species that are
    // not planetbound
    TemporaryPtr<const Planet> planet = boost::dynamic_pointer_cast<const Planet>(location);
    if (!planet)
        return false;
    const std::string& species_name = planet->SpeciesName();
    if (species_name.empty())
        return false;
    const Species* species = GetSpecies(species_name);
    if (!species)
        return false;
    if (!species->CanProduceShips())
        return false;
    // also, species that can't colonize can't produce colony ships
    if (this->CanColonize() && !species->CanColonize())
        return false;

    Empire* empire = GetEmpire(empire_id);
    if (!empire) {
        DebugLogger() << "ShipDesign::ProductionLocation: Unable to get pointer to empire " << empire_id;
        return false;
    }

    // get a source object, which is owned by the empire with the passed-in
    // empire id.  this is used in conditions to reference which empire is
    // doing the producing.  Ideally this will be the capital, but any object
    // owned by the empire will work.
    TemporaryPtr<const UniverseObject> source = SourceForEmpire(empire_id);
    // if this empire doesn't own ANYTHING, then how is it producing anyway?
    if (!source)
        return false;

    // apply hull location conditions to potential location
    const HullType* hull = GetHull();
    if (!hull) {
        ErrorLogger() << "ShipDesign::ProductionLocation  ShipDesign couldn't get its own hull with name " << m_hull;
        return false;
    }
    if (!hull->Location()->Eval(ScriptingContext(source), location))
        return false;

    // apply external and internal parts' location conditions to potential location
    for (std::vector<std::string>::const_iterator part_it = m_parts.begin(); part_it != m_parts.end(); ++part_it) {
        std::string part_name = *part_it;
        if (part_name.empty())
            continue;       // empty slots don't limit build location

        const PartType* part = GetPartType(part_name);
        if (!part) {
            ErrorLogger() << "ShipDesign::ProductionLocation  ShipDesign couldn't get part with name " << part_name;
            return false;
        }
        if (!part->Location()->Eval(ScriptingContext(source), location))
            return false;
    }
    // location matched all hull and part conditions, so is a valid build location
    return true;
}
Exemple #24
0
void FleetTransferOrder::ExecuteImpl() const {
    ValidateEmpireID();

    // look up the destination fleet
    TemporaryPtr<Fleet> target_fleet = GetFleet(DestinationFleet());
    if (!target_fleet) {
        ErrorLogger() << "Empire attempted to move ships to a nonexistant fleet";
        return;
    }
    // check that destination fleet is owned by empire
    if (!target_fleet->OwnedBy(EmpireID())) {
        ErrorLogger() << "Empire attempted to move ships to a fleet it does not own";
        return;
    }
    // verify that fleet is in a system
    if (target_fleet->SystemID() == INVALID_OBJECT_ID) {
        ErrorLogger() << "Empire attempted to transfer ships to/from fleet(s) not in a system";
        return;
    }

    // check that all ships are in the same system
    std::vector<TemporaryPtr<Ship> > ships = Objects().FindObjects<Ship>(m_add_ships);

    std::vector<TemporaryPtr<Ship> > validated_ships;
    validated_ships.reserve(m_add_ships.size());
    std::vector<int>                 validated_ship_ids;
    validated_ship_ids.reserve(m_add_ships.size());

    for (std::vector<TemporaryPtr<Ship> >::const_iterator it = ships.begin();
         it != ships.end(); ++it)
    {
        TemporaryPtr<Ship> ship = *it;
        if (!ship->OwnedBy(EmpireID()))
            continue;
        if (ship->SystemID() != target_fleet->SystemID())
            continue;
        if (ship->FleetID() == target_fleet->ID())
            continue;
        validated_ships.push_back(ship);
        validated_ship_ids.push_back(ship->ID());
    }
    if (validated_ships.empty())
        return;

    GetUniverse().InhibitUniverseObjectSignals(true);

    // remove from old fleet(s)
    std::set<TemporaryPtr<Fleet> > modified_fleets;
    for (std::vector<TemporaryPtr<Ship> >::iterator it = validated_ships.begin();
         it != validated_ships.end(); ++it)
    {
        TemporaryPtr<Ship> ship = *it;
        if (TemporaryPtr<Fleet> source_fleet = GetFleet(ship->FleetID())) {
            source_fleet->RemoveShip(ship->ID());
            modified_fleets.insert(source_fleet);
        }
        ship->SetFleetID(target_fleet->ID());
    }

    // add to new fleet
    target_fleet->AddShips(validated_ship_ids);

    GetUniverse().InhibitUniverseObjectSignals(false);

    // signal change to fleet states
    modified_fleets.insert(target_fleet);

    for (std::set<TemporaryPtr<Fleet> >::iterator it = modified_fleets.begin();
         it != modified_fleets.end(); ++it)
    {
        TemporaryPtr<Fleet> modified_fleet = *it;
        if (!modified_fleet->Empty())
            modified_fleet->StateChangedSignal();
        // if modified fleet is empty, it should be immently destroyed, so that updating it now is redundant
    }
}
int	cmdSetPath(ClientData client_data, Tcl_Interp *interp, int argc,
			   CONST84 char *argv[])
{
    Tcl_RegExp chkexpPtr;	/** Regular expression for
							 * marker checking	 **/
    char *oldpath,			/** Old value of 'var'	     **/
		 *newpath,			/** New value of 'var'	     **/
		 *sw_marker = APP_SW_MARKER,	/** arbitrary default	     **/
		 *startp = NULL, *endp = NULL,	/** regexp match endpts	     **/
		 *qualifiedpath,	/** List of dirs which
						     * are NOT already in path   **/
		**pathlist;			/** List of dirs	     **/
    const char *delim = _colon;		/** path delimiter	     **/
    int		append = 1,			/** append or prepend	     **/
			numpaths,			/** number of dirs in path   **/
			qpathlen,			/** qualifiedpath length     **/
			arg1 = 1,			/** arg start		     **/
			x;				/** loop index		     **/
    Tcl_Obj	 *np_obj;			/** new path Tcl Obj	     **/

#if WITH_DEBUGGING_CALLBACK
    ErrorLogger(NO_ERR_START, LOC, _proc_cmdSetPath, NULL);
#endif /* WITH_DEBUGGING_CALLBACK */

    /**
     **  Whatis mode?
     **/
    if (g_flags & (M_WHATIS | M_HELP)) {
        goto success0;
	}

    /**
     **   Check arguments. There should be at least 3 args:
     **     argv[0]  -  prepend/append
     **     ...
     **     argv[n-1]-  varname
     **     argv[n]  -  value
     **/
    if(argc < 3) {
		if (OK != ErrorLogger(ERR_USAGE, LOC, argv[0],
							  " path-variable directory", NULL)) {
			goto unwind0;
		}
	}

    /**
     **  Should this guy be removed from the variable(?)... If yes, then do so!
     **/
    if (g_flags & M_REMOVE) {
		return (cmdRemovePath(client_data, interp, argc, argv));   /** ----> **/
	}

    /**
     **  prepend or append. The default is append.
     **/
    if (!(append = !!strncmp(argv[0], "pre", 3))) {
		sw_marker = PRE_SW_MARKER;
	}

    /**
     **  Non-persist mode?
     **/

    if (g_flags & M_NONPERSIST) {
		return (TCL_OK);
    }

    /**
     **  Display only ... ok, let us do so!
     **/
    if (g_flags & M_DISPLAY) {
	fprintf(stderr, "%s\t ", argv[0]);
		while (--argc) {
			fprintf( stderr, "%s ", *++argv);
		}
		fprintf(stderr, "\n");
        goto success0;
    }

    /**
     **  Check for the delimiter option
     **/
    if (*(argv[arg1]) == '-') {
		if (!strcmp(argv[arg1], "-d")) {
			delim = argv[(arg1 + 1)];
			arg1 += 2;
		} else if (!strcmp(argv[arg1], "--delim")) {
			delim = argv[(arg1 + 1)];
			arg1 += 2;
		} else if (!strncmp(argv[arg1], "--delim=", 8)) {
			delim = (argv[arg1] + 8);
			arg1++;
		}
    }

    /**
     **  Get the old value of the variable. MANPATH defaults to a configure
     **  generated value.
     **  Put a \ in front of each '.' and '+'.
     **  (this is an intentional memory leak)
     **/
    oldpath = EMGetEnv(interp, argv[arg1]);
    _TCLCHK(interp)

    if(!oldpath || !*oldpath) {
		null_free((void *) &oldpath);
		oldpath = ((!strcmp(argv[arg1], "MANPATH"))
				   ? stringer(NULL, 0, DEFAULTMANPATH, NULL)
				   : stringer(NULL, 0, "", NULL));
    }

    /**
     **  Split the new path into its components directories so each
     **  directory can be checked to see whether it is already in the
     **  existing path.
     **/
    if (!(pathlist = SplitIntoList(interp, (char *)argv[(arg1 + 1)],
								   &numpaths, delim))) {
		goto unwind0;
	}

    /**
     **  Some space for the list of paths which
     **  are not already in the existing path.
     **/
    if((char *) NULL == (qualifiedpath = stringer(NULL, 0, argv[(arg1 + 1)],
												  delim, NULL))) {
		if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) {
			goto unwind1;
		}
	}

    qpathlen = (int)(strlen(qualifiedpath) + 1);
    *qualifiedpath = '\0';		/** make sure null for later	     **/

    for ((x = 0); (x < numpaths); x++) {

		regex_quote(pathlist[x], buffer, PATH_BUFLEN);

		/**
		 **  Check to see if path is already in this path variable.
		 **  It could be at the
		 **     beginning ... ^path:
		 **     middle    ... :path:
		 **     end       ... :path$
		 **     only one  ... ^path$
		 **/
		if ((char *)NULL == (newpath = stringer(NULL, 0, "(^", buffer, delim,
												")|(", delim, buffer, delim,
												")|(", delim, buffer, "$)|(^",
												buffer, "$)", NULL))) {
			if (OK != ErrorLogger( ERR_STRING, LOC, NULL)) {
				goto unwind2;
			}
		}

		np_obj = Tcl_NewStringObj(newpath, (int)strlen(newpath));
		chkexpPtr = Tcl_GetRegExpFromObj(interp, np_obj, TCL_REG_ADVANCED);
		_TCLCHK(interp)
		null_free((void *)&newpath);

		/**
		 **  If the directory is not already in the path,
		 **  add it to the qualified path.
		 **/
		if (!Tcl_RegExpExec(interp, chkexpPtr, oldpath, oldpath)) {
			if (!stringer((qualifiedpath + strlen(qualifiedpath)),
						  (int)((unsigned long)qpathlen - strlen(qualifiedpath)),
						  pathlist[x], delim, NULL)) {
				if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) {
					goto unwind2;
				}
			}
		}
    }	/** End of loop that checks for
		 ** already existent path
		 **/
    /**
     **  If all of the directories in the new path already exist,
     **  exit doing nothing.
     **/
    if (! *qualifiedpath) {
		goto success1;
	}

    /* remove trailing delimiter */
    qualifiedpath[(strlen(qualifiedpath) - 1)] = '\0';

    /**
     **  Some space for our newly created path.
     **  We size at the oldpath plus the addition.
     **/
    if (!(newpath = stringer(NULL, (int)(strlen(oldpath) + strlen(qualifiedpath) + 2), NULL))) {
		if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) {
			goto unwind2;
		}
	}
    *newpath = '\0';

    /**
     **  Easy job to do, if the old path has not been set up so far ...
     **/
    if (!strcmp(oldpath, "")) {
		strcpy(newpath, qualifiedpath);

		/**
		 **  Otherwise we have to take care on prepending vs. appending ...
		 **  If there is a append or prepend marker within the variable (see
		 **  modules_def.h) the changes are made according to this markers. Other-
		 **  wise append and prepend will be relative to the strings begin or end.
		 **/
    } else {
		Tcl_Obj *sw_obj = Tcl_NewStringObj(sw_marker, (int)strlen(sw_marker));
		Tcl_RegExp markexpPtr = Tcl_GetRegExpFromObj(interp,
													 sw_obj,
													 TCL_REG_ADVANCED);
		_TCLCHK(interp)

		strcpy(newpath, oldpath);

		if (Tcl_RegExpExec(interp, markexpPtr, oldpath, oldpath)) {
			_TCLCHK(interp)
			Tcl_RegExpRange(markexpPtr, 0,
							(CONST84 char **)&startp, (CONST84 char **)&endp);

			/**
			 **  Append/Prepend marker found
			 **/
			if (append) {
				char ch = *startp;
				*startp = '\0';
				strcpy(newpath, oldpath);
                /**
                 ** check that newpath has a value before adding delim
                 **/
				if ((strlen(newpath) > 0) &&
					(newpath[(strlen(newpath) - 1)] != *delim)) {
					strcat(newpath, delim);
				}
				strcat(newpath, qualifiedpath);
				if (newpath[strlen(newpath)-1] != *delim) {
					strcat(newpath, delim);
				}
				*startp = ch;
				strcat(newpath, startp);
			} else {
                char ch = *endp;
				*endp = '\0';
				strcpy(newpath, oldpath);
				if (newpath[strlen(newpath)-1] != *delim) {
					strcat(newpath, delim);
				}
				strcat(newpath, qualifiedpath);
				*endp = ch;
				strcat(newpath, endp);
			}
		} else {
			/**
			 **  No marker set
			 **/
			if (append) {
				strcpy(newpath, oldpath);
				if (newpath[strlen(newpath)-1] != *delim) {
					strcat(newpath, delim);
				}
				strcat(newpath, qualifiedpath);
			} else {
				strcpy(newpath, qualifiedpath);
				if (*oldpath != *delim)	{
					strcat(newpath, delim);
				}
				strcat(newpath, oldpath);
			} /* end "if (append)" */
		} /** end "if (marker)" **/
    } /** end "if (strcmp)" **/

    /**
     **  Now the new value to be set resides in 'newpath'. Set it up.
     **/
    moduleSetenv(interp, (char *)argv[arg1], newpath, 1);
    _TCLCHK(interp)

#if WITH_DEBUGGING_CALLBACK
    ErrorLogger(NO_ERR_END, LOC, _proc_cmdSetPath, NULL);
#endif /* WITH_DEBUGGING_CALLBACK */

    /**
     ** Free resources
     **/
    null_free((void *)&newpath);
success1:
    null_free((void *)&oldpath);
    null_free((void *)&qualifiedpath);
    FreeList(pathlist, numpaths);
success0:
    return (TCL_OK);			/** -------- EXIT (SUCCESS) -------> **/

unwind2:
    null_free((void *)&qualifiedpath);
unwind1:
    FreeList(pathlist, numpaths);
unwind0:
    null_free((void *)&oldpath);
    return (TCL_ERROR);			/** -------- EXIT (FAILURE) -------> **/

} /** End of 'cmdSetPath' **/
Exemple #26
0
void ColonizeOrder::ExecuteImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();

    TemporaryPtr<Ship> ship = GetShip(m_ship);
    if (!ship) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl couldn't get ship with id " << m_ship;
        return;
    }
    if (!ship->CanColonize()) { // verifies that species exists and can colonize and that ship can colonize
        ErrorLogger() << "ColonizeOrder::ExecuteImpl got ship that can't colonize";
        return;
    }
    if (!ship->OwnedBy(empire_id)) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl got ship that isn't owned by the order-issuing empire";
        return;
    }

    float colonist_capacity = ship->ColonyCapacity();

    TemporaryPtr<Planet> planet = GetPlanet(m_planet);
    if (!planet) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl couldn't get planet with id " << m_planet;
        return;
    }
    if (planet->CurrentMeterValue(METER_POPULATION) > 0.0f) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that already has population";
        return;
    }
    if (!planet->Unowned() && planet->Owner() != empire_id) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that owned by another empire";
        return;
    }
    if (planet->OwnedBy(empire_id) && colonist_capacity == 0.0f) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that is already owned by empire and colony ship with zero capcity";
        return;
    }
    if (GetUniverse().GetObjectVisibilityByEmpire(m_planet, empire_id) < VIS_PARTIAL_VISIBILITY) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that empire has insufficient visibility of";
        return;
    }
    if (colonist_capacity > 0.0f && planet->EnvironmentForSpecies(ship->SpeciesName()) < PE_HOSTILE) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl nonzero colonist capacity and planet that ship's species can't colonize";
        return;
    }

    int ship_system_id = ship->SystemID();
    if (ship_system_id == INVALID_OBJECT_ID) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given id of ship not in a system";
        return;
    }
    int planet_system_id = planet->SystemID();
    if (ship_system_id != planet_system_id) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given ids of ship and planet not in the same system";
        return;
    }
    if (planet->IsAboutToBeColonized()) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given id planet that is already being colonized";
        return;
    }

    planet->SetIsAboutToBeColonized(true);
    ship->SetColonizePlanet(m_planet);

    if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID()))
        fleet->StateChangedSignal();
}
static int Remove_Path(Tcl_Interp *interp, char *variable, char *item,
					   char *sw_marker, const char *delim)
{
	char    *oldpath,	/** current path  **/
			*olditem;	/** item from path **/
	int     i = 0,		/** counter **/
			found = 0,	/** flag to indicate item was found **/
			pcount = 0,	/** count of items in path **/
			addsep = 0,	/** flag to add separator **/
			marked = 0,	/** flag path contains sw_marker **/
			oldpathlen = 0;
	Tcl_DString     _newpath;
	Tcl_DString    *newpath = &_newpath;
	Tcl_DStringInit(newpath);
    /**
     **  Get the current value of the "PATH" environment variable
     **/
	oldpath = (char *)EMGetEnv(interp, variable);
	if (!oldpath || !*oldpath) {
		null_free((void *)&oldpath);
		_TCLCHK(interp);
		goto success0;		/** -------- EXIT (SUCCESS) -------> **/
	}
	/* copy oldpath to not mess with the TCL value of env(PATH) */
	if (!(oldpath = stringer(NULL,0, oldpath, NULL))) {
		if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) {
			goto unwind0;
		}
	}

	/* get length of oldpath before it gets modified by xstrtok */
	oldpathlen = (int)strlen(oldpath);

	/* determine if sw_marker is in the path */
	olditem = xstrtok(oldpath, delim);
	while (olditem) {
		if (!strcmp(olditem, sw_marker)) {
			marked = 1;
		}
		pcount++;
		olditem = xstrtok(NULL, delim);
	}

	/** pointer arithmetic on oldpath
	 ** if olditem starts at terminating null string of oldpath,
	 ** it means the last character in oldpath was ":", meaning
	 ** the last element was the empty string.  use <= to catch
	 **  this case and process the last empty element
	 */
	for (olditem = oldpath; olditem <= oldpath + oldpathlen;
	     olditem += strlen(olditem) + 1) {

		if (strcmp(olditem, item)) {
			/* not the droids we're looking for */
			if (Tcl_DStringLength(newpath)) {
				if (!Tcl_DStringAppend(newpath, delim, 1))
					if (OK !=
					    ErrorLogger(ERR_STRING, LOC, NULL))
						goto unwind1;
			}
			if (!Tcl_DStringAppend(newpath, olditem, -1))
				if (OK != ErrorLogger(ERR_STRING, LOC, NULL))
					goto unwind1;
		} else {
			/* bingo! Don't add it to new path  */
			found++;

			if ((g_flags & M_SWSTATE1) && !marked) {
			/**
			 **  In state1, we're actually replacing old paths with
			 **  the markers for future appends and prepends.
			 **
			 **  We only want to do this once to mark the location
			 **  the module was formed around.
			 **/
				marked = 1;
				if (Tcl_DStringLength(newpath)) {
					if (!Tcl_DStringAppend
					    (newpath, delim, 1))
						if (OK !=
						    ErrorLogger(ERR_STRING, LOC,
								NULL))
							goto unwind1;
				}
				if (!Tcl_DStringAppend(newpath, sw_marker, -1))
					if (OK !=
					    ErrorLogger(ERR_STRING, LOC, NULL))
						goto unwind1;
			}
		}
	}

	if (!found) {
		goto success1;
	}

	if (Tcl_DStringLength(newpath)) {
		/**
		**  Cache the set.  Clear the variable from the unset table just
		**  in case it was previously unset.
		**/
		store_hash_value(setenvHashTable, variable,
			Tcl_DStringValue(newpath));
		clear_hash_value(unsetenvHashTable, variable);

		/**
		**  Store the new PATH value into the environment.
		**/
		(void) EMSetEnv( interp, variable, Tcl_DStringValue(newpath));

		_TCLCHK(interp);
	} else {
		/**
		 **  In this case, I should go ahead and unset the variable
		 **  from the environment because I'm removing the very last
		 **  path.
		 **
		 **  First I'm going to clear the variable from the
		 **  setenvHashTable just in case its already been altered
		 **  and had a significant value at the time. It's very
		 **  possible that I'm removing the only two or three paths
		 **  from this variable. If that's the case, then all the
		 **  earlier paths were marked for output in this hashTable.
		 **
		 **  Secondly, I actually mark the the environment variable
		 **  to be unset when output.
		 **/
		clear_hash_value(setenvHashTable, variable);
		moduleUnsetenv(interp, variable);

		/**
		 **  moduleUnsetenv doesn't unset the variable in the Tcl
		 **  space because the $env variable might need to be
		 **  used again in the modulefile for locating other
		 **  paths.  BUT, since this was a path-type environment
		 **  variable, the user is expecting this to be empty
		 **  after removing the only remaining path.  So, I set
		 **  the variable empty here.
		 **/
		(void) EMSetEnv( interp, variable, "");
		_TCLCHK(interp);
	}

/**
 **  Free what has been used and return on success
 **/
success1:
	null_free((void *)&oldpath);
success0:
	Tcl_DStringFree(newpath);
	return (TCL_OK);		/** -------- EXIT (SUCCESS) -------> **/

unwind1:
	null_free((void *)&oldpath);
unwind0:
	Tcl_DStringFree(newpath);
	return (TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/

} /** End of 'Remove_Path' **/
Exemple #28
0
void InvadeOrder::ExecuteImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();

    TemporaryPtr<Ship> ship = GetShip(m_ship);
    if (!ship) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl couldn't get ship with id " << m_ship;
        return;
    }
    if (!ship->HasTroops()) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl got ship that can't invade";
        return;
    }
    if (!ship->OwnedBy(empire_id)) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl got ship that isn't owned by the order-issuing empire";
        return;
    }

    TemporaryPtr<Planet> planet = GetPlanet(m_planet);
    if (!planet) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl couldn't get planet with id " << m_planet;
        return;
    }
    if (planet->Unowned() && planet->CurrentMeterValue(METER_POPULATION) == 0.0) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl given unpopulated planet";
        return;
    }
    if (planet->CurrentMeterValue(METER_SHIELD) > 0.0) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl given planet with shield > 0";
        return;
    }
    if (planet->OwnedBy(empire_id)) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl given planet that is already owned by the order-issuing empire";
        return;
    }
    if (!planet->Unowned() && Empires().GetDiplomaticStatus(planet->Owner(), empire_id) != DIPLO_WAR) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl given planet owned by an empire not at war with order-issuing empire";
        return;
    }
    if (GetUniverse().GetObjectVisibilityByEmpire(m_planet, empire_id) < VIS_BASIC_VISIBILITY) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl given planet that empire reportedly has insufficient visibility of, but will be allowed to proceed pending investigation";
        //return;
    }

    int ship_system_id = ship->SystemID();
    if (ship_system_id == INVALID_OBJECT_ID) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl given id of ship not in a system";
        return;
    }
    int planet_system_id = planet->SystemID();
    if (ship_system_id != planet_system_id) {
        ErrorLogger() << "InvadeOrder::ExecuteImpl given ids of ship and planet not in the same system";
        return;
    }

    // note: multiple ships, from same or different empires, can invade the same planet on the same turn
    DebugLogger() << "InvadeOrder::ExecuteImpl set for ship " << m_ship << " "
                  << ship->Name() << " to invade planet " << m_planet << " " << planet->Name();
    planet->SetIsAboutToBeInvaded(true);
    ship->SetInvadePlanet(m_planet);

    if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID()))
        fleet->StateChangedSignal();
}
int	cmdModuleWhatis(	ClientData	 client_data,
		      		Tcl_Interp	*interp,
		      		int		 argc,
		      		CONST84 char	*argv[])
{
    int i = 1;

#if WITH_DEBUGGING_CALLBACK
    ErrorLogger( NO_ERR_START, LOC, _proc_cmdModuleWhatis, NULL);
#endif

    /**
     **  Help mode
     **/

    if( g_flags & M_HELP)
        return( TCL_OK);		/** -------- EXIT (SUCCESS) -------> **/

    /**
     **  Parameter check
     **/

    if( argc < 2) {
	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], " string", NULL))
	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
    }
  
    /**
     **  If we don't have any whatis list buffer until now, we will create one
     **/

    if( !whatis) {
	whatis_size = WHATIS_FRAG;
	if((char **) NULL
		== (whatis = module_malloc(whatis_size * sizeof(char *)))){
	    ErrorLogger( ERR_ALLOC, LOC, NULL);
	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
	}
    }

    /**
     **  Display mode?
     **/

    if( g_flags & M_DISPLAY) {
	fprintf( stderr, "%s\t ", argv[ 0]);
	for( i=1; i<argc; i++)
	    fprintf( stderr, "%s ", argv[ i]);
	fprintf( stderr, "\n");
        return( TCL_OK);		/** ------- EXIT PROCEDURE -------> **/
    }

    /**
     **  Check if printing is requested 
     **/

    if( g_flags & M_WHATIS ) {
	while( i < argc) {

	    /**
	     **  Conditionally we have to enlarge our buffer
	     **/

	    while( whatis_ndx + 2 >= whatis_size) {
		whatis_size += WHATIS_FRAG;
		if(!(whatis = module_realloc( whatis, whatis_size *
		    sizeof( char *)))) {
		    ErrorLogger( ERR_ALLOC, LOC, NULL);
		    return( TCL_ERROR);	/** -------- EXIT (FAILURE) -------> **/
		}
	    }

	    /**
	     **  Put the string on the buffer
	     **/

	    if((char *) NULL == (whatis[ whatis_ndx++] = strdup( argv[ i++]))) {
		if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
		    return( TCL_ERROR);
		whatis_ndx--;
	    }

	} /** while **/
    } /** if **/

    /**
     **  Put a trailing terminator on the buffer
     **/

    whatis[ whatis_ndx] = (char *) NULL;

#if WITH_DEBUGGING_CALLBACK
    ErrorLogger( NO_ERR_END, LOC, _proc_cmdModuleWhatis, NULL);
#endif

    return( TCL_OK);

} /** End of 'cmdModuleWhatis' **/
Exemple #30
0
void SaveGame(const std::string& filename, const ServerSaveGameData& server_save_game_data,
              const std::vector<PlayerSaveGameData>& player_save_game_data,
              const Universe& universe, const EmpireManager& empire_manager,
              const SpeciesManager& species_manager, const CombatLogManager& combat_log_manager,
              const GalaxySetupData& galaxy_setup_data, bool multiplayer)
{
    DebugLogger() << "SaveGame:: filename: " << filename;
    GetUniverse().EncodingEmpire() = ALL_EMPIRES;

    std::map<int, SaveGameEmpireData> empire_save_game_data = CompileSaveGameEmpireData(empire_manager);
    SaveGamePreviewData save_preview_data;
    CompileSaveGamePreviewData(server_save_game_data, player_save_game_data, empire_save_game_data, save_preview_data);

    try {
        fs::path path = FilenameToPath(filename);
        // A relative path should be relative to the save directory.
        if (path.is_relative()) {
            path = GetSaveDir()/path;
            DebugLogger() << "Made save path relative to save dir. Is now: " << path;
        }

        if (multiplayer) {
            // Make sure the path points into our save directory
            if (!IsInside(path, GetSaveDir())){
                path = GetSaveDir() / path.filename();
            }
        }

        fs::ofstream ofs(path, std::ios_base::binary);

        if (!ofs)
            throw std::runtime_error(UNABLE_TO_OPEN_FILE);

        if (GetOptionsDB().Get<bool>("binary-serialization")) {
            freeorion_bin_oarchive oa(ofs);
            oa << BOOST_SERIALIZATION_NVP(save_preview_data);
            oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data);
            oa << BOOST_SERIALIZATION_NVP(server_save_game_data);
            oa << BOOST_SERIALIZATION_NVP(player_save_game_data);
            oa << BOOST_SERIALIZATION_NVP(empire_save_game_data);
            oa << BOOST_SERIALIZATION_NVP(empire_manager);
            oa << BOOST_SERIALIZATION_NVP(species_manager);
            oa << BOOST_SERIALIZATION_NVP(combat_log_manager);
            Serialize(oa, universe);
        } else {
            freeorion_xml_oarchive oa(ofs);
            oa << BOOST_SERIALIZATION_NVP(save_preview_data);
            oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data);
            oa << BOOST_SERIALIZATION_NVP(server_save_game_data);
            oa << BOOST_SERIALIZATION_NVP(player_save_game_data);
            oa << BOOST_SERIALIZATION_NVP(empire_save_game_data);
            oa << BOOST_SERIALIZATION_NVP(empire_manager);
            oa << BOOST_SERIALIZATION_NVP(species_manager);
            oa << BOOST_SERIALIZATION_NVP(combat_log_manager);
            Serialize(oa, universe);
        }
    } catch (const std::exception& e) {
        ErrorLogger() << UserString("UNABLE_TO_WRITE_SAVE_FILE") << " SaveGame exception: " << ": " << e.what();
        throw e;
    }
}