예제 #1
0
void connectserv(const char *servername, int serverport, const char *serverpassword)
{
    if(connpeer)
    {
        conoutf("aborting connection attempt");
        abortconnect();
    }

    if(serverport <= 0) serverport = server::serverport();

    ENetAddress address;
    address.port = serverport;

    if(servername)
    {
        if(strcmp(servername, connectname)) setsvar("connectname", servername);
        if(serverport != connectport) setvar("connectport", serverport);
        conoutf("attempting to connect to %s:%d", servername, serverport);
        if(!resolverwait(servername, &address))
        {
            conoutf("\f3could not resolve server %s", servername);
            return;
        }
    }
    else
    {
        setsvar("connectname", "");
        setvar("connectport", 0);
        conoutf("attempting to connect over LAN");
        address.host = ENET_HOST_BROADCAST;
    }

    if(!clienthost)
    {
        clienthost = enet_host_create(NULL, 2, server::numchannels(), rate*1024, rate*1024);
        if(!clienthost)
        {
            conoutf("\f3could not connect to server");
            return;
        }
        clienthost->duplicatePeers = 0;
    }

    connpeer = enet_host_connect(clienthost, &address, server::numchannels(), 0);
    enet_host_flush(clienthost);
    connmillis = totalmillis;
    connattempts = 0;
}
예제 #2
0
//! The user picks 'upload map' in the GUI.
//! First we save the map. Then we call Python, which packages the map
//! and uploads it to the correct asset server, then notify the instance we
//! are connected to that the map has been updated, which then gets and runs
//! that new map. That process causes it to tell all clients of a new map that
//! they should get, which makes them get the new version. Among those clients is
//! this one, the uploader, which we do not treat differently in that respect.
void do_upload()
{
    renderprogress(0.1, "compiling scripts...");

    // Make sure the script compiles ok TODO: All scripts, not just the main one
    REFLECT_PYTHON( get_map_script_filename );
    std::string filename = boost::python::extract<std::string>( get_map_script_filename() );
    if (!checkCompile(filename))
        return;

    // Save ogz
    renderprogress(0.3, "generating map...");
    save_world(game::getclientmap());

// load_world: ogzname, mname, cname: packages/base/spiral/map.ogz,base/spiral/map,(null)
// save_world ogzname, mname, cname: packages//packages.ogz,/packages

    // Save entities (and backup)
    renderprogress(0.4, "exporting entities...");
    REFLECT_PYTHON( export_entities );
    export_entities("entities.json");

    // Do the upload
    renderprogress(0.5, "uploading map...");
    REFLECT_PYTHON( upload_map );
    upload_map();

    // Remember asset
    REFLECT_PYTHON( get_curr_map_asset_id );
    std::string assetId = boost::python::extract<std::string>( get_curr_map_asset_id() );
    setsvar("last_uploaded_map_asset", assetId.c_str());
}
예제 #3
0
void connectserv(const char *name, int port, const char *password)
{
    abortconnect();
    if(!port) port = ENG_SERVER_PORT;

    ENetAddress address;
    address.port = port;

    setsvar("serveraddress", "");
    setvar("serverconport", 0);
    if(name && *name)
    {
        addserver(name, port);
        conoutft(CON_MESG, "\faattempting to connect to %s:[%d]", name, port);
        if(!resolverwait(name, &address))
        {
            conoutft(CON_MESG, "\frcould not resolve host %s", name);
            connectfail();
            return;
        }
        setsvar("serveraddress", name);
        setvar("serverconport", port);
    }
    else
    {
        conoutft(CON_MESG, "\faattempting to connect to a local server");
        address.host = ENET_HOST_BROADCAST;
    }

    if(!clienthost)
        clienthost = enet_host_create(NULL, 2, server::numchannels(), rate, rate);

    if(clienthost)
    {
        connpeer = enet_host_connect(clienthost, &address, server::numchannels(), 0);
        enet_host_flush(clienthost);
        connmillis = totalmillis;
        connattempts = 0;
        client::connectattempt(name ? name : "", port, password ? password : "", address);
        conoutft(CON_MESG, "\fgconnecting to %s:[%d]", name != NULL ? name : "local server", port);
    }
    else
    {
        conoutft(CON_MESG, "\frfailed creating client socket");
        connectfail();
    }
}
예제 #4
0
static PyObject *setVariable(PyObject *self, PyObject *args)
{
    char *variableName;
    char *value;
    if(!PyArg_ParseTuple(args, "ss", &variableName, &value))
    	return 0;
    static string scmdval; scmdval[0] = 0;
    ident *id = idents->access(variableName);
    if(id)
    {
        switch(id->type)
        {
			case ID_VAR:
			{
                int ret = parseint(value);
                if(ret < id->minval || ret > id->maxval)
                {
                	PyErr_Format(PyExc_ValueError,
                        id->flags&IDF_HEX ?
                                (id->minval <= 255 ? "valid range for %s is %d..0x%X" : "valid range for %s is 0x%X..0x%X") :
                                "valid range for %s is %d..%d", variableName, id->minval, id->maxval);
                    return 0;
                }
                setvar(variableName, ret);
				break;
			}
			case ID_FVAR:
			{
                float ret = parsefloat(value);
                if(ret < id->minvalf || ret > id->maxvalf)
                {
                	PyErr_Format(PyExc_ValueError, "valid range for %s is %s..%s", variableName, floatstr(id->minvalf), floatstr(id->maxvalf));
                    return 0;
                }
                setfvar(variableName, ret);
                break;
			}
			case ID_SVAR:
			{
                setsvar(variableName, value);
				break;
			}
			default:
			{
				PyErr_SetString(PyExc_ValueError, "Unknown server variable type");
				return 0;
				break;
			}
        }
        printf("hopefully to set: %s to %s\n", variableName, value);
    	Py_INCREF(Py_None);
    	return Py_None;
    }
	PyErr_SetString(PyExc_ValueError, "Invalid variable specified");
	return 0;
}
예제 #5
0
// Get instance data and create a GUI for it
void show_instances()
{
    REFLECT_PYTHON( get_possible_instances );

    boost::python::object instances = get_possible_instances();

    REFLECT_PYTHON( None );

    if (instances == None)
    {
        setsvar("error_message", "Could not get the list of instances");
        showgui("error");
        return;
    }

    std::string command =
        "newgui instances [\n"
        "    guitext \"Pick an instance to enter:\"\n"
        "    guibar\n";

    int numInstances = boost::python::extract<int>(instances.attr("__len__")());

    for (int i = 0; i < numInstances; i++)
    {
        boost::python::object instance = instances[i];
        std::string instance_id = boost::python::extract<std::string>(instance.attr("__getitem__")("instance_id"));
        std::string event_name = boost::python::extract<std::string>(instance.attr("__getitem__")("event_name"));

        assert( Utility::validateAlphaNumeric(instance_id) );
        assert( Utility::validateAlphaNumeric(event_name, " (),.;") ); // XXX: Allow more than alphanumeric+spaces: ()s, .s, etc.

        command += "    guibutton \"" + event_name + "\" \"connect_to_instance " + instance_id + "\"\n";
    }

    command += "]\n";
    command += "showgui instances\n";

    Logging::log(Logging::DEBUG, "Instances GUI: %s\r\n", command.c_str());

    execute(command.c_str());
}
// Sets up a GUI for editing an entity's state data
void prepare_entity_gui()
{
    GuiControl::EditedEntity::stateData.clear();
    GuiControl::EditedEntity::sortedKeys.clear();

    GuiControl::EditedEntity::currEntity = TargetingControl::targetLogicEntity;
    if (GuiControl::EditedEntity::currEntity->isNone())
    {
        Logging::log(Logging::DEBUG, "No entity to show the GUI for\r\n");
        return;
    }

    int uniqueId = GuiControl::EditedEntity::currEntity->getUniqueId();
    ScriptValuePtr stateData = ScriptEngineManager::runScript(
        "getEntity(" + Utility::toString(uniqueId) + ").createStateDataDict()"
    );

    ScriptValuePtr keys = ScriptEngineManager::getGlobal()->call("keys", stateData);

    num_entity_gui_fields = keys->getPropertyInt("length");

    // Save the stateData, to see what changed and what didn't
    for (int i = 0; i < num_entity_gui_fields; i++)
    {
        std::string key = keys->getPropertyString( Utility::toString(i) );
        std::string guiName = ScriptEngineManager::getGlobal()->call(
            "__getVariableGuiName",
            ScriptValueArgs().append(uniqueId).append(key)
        )->getString();

        std::string value = stateData->getPropertyString(key);

        GuiControl::EditedEntity::stateData.insert(
            GuiControl::EditedEntity::StateDataMap::value_type(
                key,
                std::pair<std::string, std::string>(
                    guiName,
                    value
                )
            )
        );

//        std::string a = python::extract<std::string>( keys[i] );
//        std::string b = python::extract<std::string>( pythonStateData[keys[i]] );

        GuiControl::EditedEntity::sortedKeys.push_back( key );
    }

    sort( GuiControl::EditedEntity::sortedKeys.begin(), GuiControl::EditedEntity::sortedKeys.end() ); // So order is always the same

    for (int i = 0; i < num_entity_gui_fields; i++)
    {
        std::string key = GuiControl::EditedEntity::sortedKeys[i];
        std::string guiName = GuiControl::EditedEntity::stateData[key].first;
        std::string value = GuiControl::EditedEntity::stateData[key].second;

        std::string fieldName = "entity_gui_field_" + Utility::toString(i);
        std::string labelName = "entity_gui_label_" + Utility::toString(i);

        setsvar((char*)fieldName.c_str(), (char*)value.c_str());
        setsvar((char*)labelName.c_str(), (char*)guiName.c_str());
    }

    // Title
    std::string title = GuiControl::EditedEntity::currEntity->scriptEntity->getPropertyString("_class");
    title = Utility::toString(uniqueId) + ": " + title;

    setsvar((char*)"entity_gui_title", (char*)title.c_str());

    // Create the gui
    std::string command =
    "newgui entity [\n"
    "    guitext $entity_gui_title\n"
    "    guibar\n";

    for (int i = 0; i < num_entity_gui_fields; i++)
    {
        std::string sI = Utility::toString(i);
        std::string key = GuiControl::EditedEntity::sortedKeys[i];
        std::string value = GuiControl::EditedEntity::stateData[key].second;

        if (value.size() > 50)
        {
            Logging::log(Logging::WARNING, "Not showing field '%s' as it is overly large for the GUI\r\n", key.c_str());
            continue; // Do not even try to show overly-large items
        }

        command +=
    "    guilist [\n"
    "        guitext (get_entity_gui_label " + sI + ")\n"
    "        new_entity_gui_field_" + sI + " = (get_entity_gui_value " + sI + ")\n"
    "        guifield new_entity_gui_field_" + sI + " " + Utility::toString((int)value.size()+25) + " [set_entity_gui_value " + sI + " $new_entity_gui_field_" + sI + "] 0\n"
    "    ]\n";

        if ((i+1) % 10 == 0)
        {
            command +=
    "   guitab " + Utility::toString(i) + "\n";
        }
    }

    command +=
    "]";

//    printf("Command: %s\r\n", command.c_str());
    execute(command.c_str());
}