Ejemplo n.º 1
0
bool HandleRconCommands(AMX *amx, cell *params, cell *retval) {
    char buf[64];
    cell* addr;
    amx_GetAddr(amx, params[1], &addr);
    amx_GetString(buf, addr, 0, 64);

    if (!strcmp(buf, "sampsharpstop")) {
        if (!GameMode::IsLoaded()) {
            logprintf("A gamemode must be loaded in order to stop.");
            return false;
        }

        logprintf("Stopping SampSharp...");
        run_signal = -1;
        signal_amx = amx;

        return false;
    }
    if (!strcmp(buf, "sampsharpstart")) {
        if (!initial_load) {
            logprintf("OnGameModeInit needs to be called first.");
            return false;
        }
        if (GameMode::IsLoaded()) {
            logprintf("You need to stop the gamemode before you can start it.");
            return false;
        }

        logprintf("Starting SampSharp...");
        run_signal = 1;
        signal_amx = amx;

        return false;
    }
}
Ejemplo n.º 2
0
PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) {
    if (!sampgdk::Load(ppData)) return false;

    pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
    logprintf("");
    logprintf("SampSharp Plugin");
    logprintf("----------------");
    logprintf("v%s, (C)2014-2015 Tim Potze", PLUGIN_VERSION);
    logprintf("");

    Config::Read();
    return true;
}
Ejemplo n.º 3
0
void unloadGamemode() {
    if (!GameMode::IsLoaded()) return;

    string namespase = Config::GetGameModeNameSpace();
    string klass = Config::GetGameModeClass();

    logprintf("");
    logprintf("---------------");
    logprintf("Unloading gamemode: %s:%s", namespase.c_str(), klass.c_str());

    GameMode::Unload();

    logprintf("  Unloaded.");
    logprintf("");
}
Ejemplo n.º 4
0
void convertSymbols() {
    string symbols = Config::GetSymbolFiles();

    if (symbols.length() > 0) {
        logprintf("Symbol file generation");
        logprintf("----------------------");

        stringstream symbols_stream(symbols);
        string file;
        int successes = 0;
        while (std::getline(symbols_stream, file, ' ')) {
            logprintf("Converting: %s", file.c_str());

            std::ifstream ifile(file.c_str());
            if (file.empty() || !ifile) {
                logprintf("  Failed.");
                continue;
            }
            mono_convert_symbols(file.c_str());

            successes++;
            logprintf("  Converted.");
        }
        logprintf(" Converted %d files.", successes);
        logprintf("");
    }
}
Ejemplo n.º 5
0
void loadGamemode() {
    if (GameMode::IsLoaded()) return;

    // Load empty filterscript.
    if (!filterscript_loaded) {
        SendRconCommand("loadfs empty");
        filterscript_loaded = true;
    }

    // Load mono.
    if (!MonoRuntime::IsLoaded()) {
        MonoRuntime::Load(Config::GetMonoAssemblyDir(),
            Config::GetMonoConfigDir(), Config::GetTraceLevel(),
            PathUtil::GetPathInBin("gamemode/")
            .append(Config::GetGameModeNameSpace()).append(".dll"));
    }

    // Load game mode.
    string namespaceName = Config::GetGameModeNameSpace();
    string className = Config::GetGameModeClass();

    logprintf("Gamemode");
    logprintf("---------------");
    logprintf("Loading gamemode: %s:%s", namespaceName.c_str(),
        className.c_str());

    if (GameMode::Load(Config::GetGameModeNameSpace(),
        Config::GetGameModeClass()))
        logprintf("  Loaded.");
    else
        logprintf("  Failed.");

    logprintf("");
}
Ejemplo n.º 6
0
void ProcessSignals() {
    // Process run signals.
    if (run_signal == -1) {
        cell noParams[1];
        noParams[0] = 0;
        cell unhandledRetval;

        GameMode::ProcessPublicCall(signal_amx, "OnGameModeExit", noParams,
            &unhandledRetval);

        unloadGamemode();

        logprintf("");
        logprintf("=================================");
        logprintf("> SampSharp gamemode has stopped!");
        logprintf("> Replace your gamemode files and run `sampsharp start`");
        logprintf("=================================");
        logprintf("");

        run_signal = 0;
    }
    else if (run_signal == 1) {
        loadGamemode();

        cell noParams[1];
        noParams[0] = 0;
        cell unhandledRetval;

        GameMode::ProcessPublicCall(signal_amx, "OnGameModeInit", noParams,
            &unhandledRetval);

        run_signal = 0;
    }
}
Ejemplo n.º 7
0
void loadGamemode() {
    if (GameMode::IsLoaded()) return;

    /* Load empty filterscript */
    if (!filterscript_loaded) {
        SendRconCommand("loadfs empty");
        filterscript_loaded = true;
    }

    /* Load mono */
    if (!MonoRuntime::IsLoaded()) {
        MonoRuntime::Load(Config::GetMonoAssemblyDir(),
            Config::GetMonoConfigDir(), Config::GetTraceLevel(),
            PathUtil::GetPathInBin("gamemode/")
            .append(Config::GetGameModeNameSpace()).append(".dll"));
    }

    /* Set initial codepage to the configured one. */
    int codepage = Config::GetCodepage();
    set_codepage(codepage);

    convertSymbols();

    /* Load game mode */
    string namespaceName = Config::GetGameModeNameSpace();
    string className = Config::GetGameModeClass();

    logprintf("Gamemode");
    logprintf("---------------");
    logprintf("Loading gamemode: %s:%s", namespaceName.c_str(),
        className.c_str());

    if (GameMode::Load(Config::GetGameModeNameSpace(),
        Config::GetGameModeClass()))
        logprintf("  Loaded.");
    else
        logprintf("  Failed.");

    logprintf("");
}
Ejemplo n.º 8
0
void samphp_error_handler(char *str)
{
	logprintf(str);
}
Ejemplo n.º 9
0
int samphp_output_handler(const char *str, unsigned int str_length)
{
	logprintf(str);
	return str_length;
}
Ejemplo n.º 10
0
PLUGIN_EXPORT bool PLUGIN_CALL OnPublicCall(AMX *amx, const char *name,
    cell *params, cell *retval) {
    if (!GameMode::IsLoaded() && !strcmp(name, "OnGameModeInit")) {
        /* Load empty filterscript */
        if (!filterscript_loaded) {
            SendRconCommand("loadfs empty");
            filterscript_loaded = true;
        }

        /* Load mono */
        if (!MonoRuntime::IsLoaded()) {
            MonoRuntime::Load(Config::GetMonoAssemblyDir(),
                Config::GetMonoConfigDir(), Config::GetTraceLevel(),
                PathUtil::GetPathInBin("gamemode/")
                .append(Config::GetGameModeNameSpace()).append(".dll"));
        }

        /* Set initial codepage to the configured one. */
        int codepage = Config::GetCodepage();
        set_codepage(codepage);

        convertSymbols();

        /* Load game mode */
        string namespaceName = Config::GetGameModeNameSpace();
        string className = Config::GetGameModeClass();

        logprintf("Gamemode");
        logprintf("---------------");
        logprintf("Loading gamemode: %s:%s", namespaceName.c_str(),
            className.c_str());

        if(GameMode::Load(Config::GetGameModeNameSpace(),
            Config::GetGameModeClass()))
            logprintf("  Loaded.");
        else
            logprintf("  Failed.");

        logprintf("");
    }
    else if (GameMode::IsLoaded() && !strcmp(name, "OnGameModeExit")) {
        GameMode::ProcessPublicCall(amx, name, params, retval);

        string namespaceName = Config::GetGameModeNameSpace();
        string className = Config::GetGameModeClass();

        logprintf("");
        logprintf("---------------");
        logprintf("Unloading gamemode: %s:%s", namespaceName.c_str(),
            className.c_str());

        GameMode::Unload();

        logprintf("  Unloaded.");
        logprintf("");
    }

    if (GameMode::IsLoaded()) {
        GameMode::ProcessPublicCall(amx, name, params, retval);
    }

    return true;
}
Ejemplo n.º 11
0
void GameMode::ProcessPublicCall(AMX *amx, const char *name, cell *params,
    cell *retval) {

    CallbackSignature *signature;

    if (!isLoaded_) {
        return;
    }

    int param_count = params[0] / sizeof(cell);
    if (strlen(name) == 0 || param_count > MAX_CALLBACK_PARAM_COUNT) {
        logprintf("[SampSharp] WARNING: Skipped callback with %d parameters.",
            param_count);
        return;
    }

    /* OnRconCommand can sometimes end up on different theads?
     * Just to make sure, attach the current thread to the domain.
     */
    mono_thread_attach(domain_);

    /* If the callback not known in the callbacks_ map, find the callback in
     * the game mode or one of the registered extensions.
     */
    if (callbacks_.find(name) == callbacks_.end()) {
        signature = new CallbackSignature;
        signature->method = FindMethodForCallback(name, param_count,
            signature->handle);

        if (!signature->method) {
            callbacks_[name] = NULL;
            return;
        }

        MonoImage *image = mono_class_get_image(
            mono_method_get_class(signature->method));

        void *iter = NULL;
        int iter_idx = 0;

        MonoMethodSignature *sig = mono_method_get_signature(signature->method,
            image, mono_method_get_token(signature->method));

        MonoType* type = NULL;
        while (type = mono_signature_get_params(sig, &iter)) {
            ParameterSignature parameter_signature;

            parameter_signature.type = GetParameterType(type);

            if (parameter_signature.type == PARAM_INT_ARRAY ||
                parameter_signature.type == PARAM_FLOAT_ARRAY ||
                parameter_signature.type == PARAM_BOOL_ARRAY) {
                parameter_signature.length_idx = GetParamLengthIndex(
                    signature->method, iter_idx);

                if (parameter_signature.length_idx == -1) {
                    callbacks_[name] = NULL;
                    return;
                }
            }

            signature->params[iter_idx++] = parameter_signature;
        }

        callbacks_[name] = signature;
    }

    if (signature = callbacks_[name]) {
        /* Handle calls without parameters. */
        if (!param_count) {
            int retint = CallEvent(signature->method, signature->handle, NULL, NULL);

            /* If there's a cell allocated for the return value and
             * the callback was executed successfuly, fill the cell with
             * the returned value.
             */
            if (retval != NULL && retint != -1) {
                *retval = retint;
            }
            return;
        }

        /* Handle calls with parameters. */

        void *args[MAX_CALLBACK_PARAM_COUNT];
        int len = 0;
        cell *addr = NULL;
        MonoArray *arr;

        if (signature->params.size() != param_count)
        {
            logprintf("[SampSharp] ERROR: Parameters of callback %s "
                "does not match signature (called: %d, signature: %d)",
                name, param_count, signature->params.size());
            return;
        }

        for (int i = 0; i < param_count; i++) {
            switch (signature->params[i].type) {
            case PARAM_INT:
            case PARAM_FLOAT:
            case PARAM_BOOL: {
                args[i] = &params[i + 1];
                break;
            }
            case PARAM_STRING: {
                amx_GetAddr(amx, params[i + 1], &addr);
                amx_StrLen(addr, &len);

                if (len) {
                    len++;

                    char* text = new char[len];

                    amx_GetString(text, addr, 0, len);
                    args[i] = string_to_monostring(text, len);
                }
                else {
                    args[i] = mono_string_new(mono_domain_get(), "");
                }
                break;
            }

            case PARAM_INT_ARRAY: {
                len = params[signature->params[i].length_idx];
                arr = mono_array_new(mono_domain_get(), mono_get_int32_class(),
                    len);

                if (len > 0) {
                    cell* addr = NULL;
                    amx_GetAddr(amx, params[i + 1], &addr);

                    for (int i = 0; i < len; i++) {
                        mono_array_set(arr, int, i, *(addr + i));
                    }
                }
                args[i] = arr;
                break;
            }
            case PARAM_FLOAT_ARRAY: {
                len = params[signature->params[i].length_idx];
                arr = mono_array_new(mono_domain_get(), mono_get_int32_class(),
                    len);

                if (len > 0) {
                    cell* addr = NULL;
                    amx_GetAddr(amx, params[i + 1], &addr);

                    for (int i = 0; i < len; i++) {
                        mono_array_set(arr, float, i, amx_ctof(*(addr + i)));
                    }
                }
                args[i] = arr;
                break;
            }
            case PARAM_BOOL_ARRAY: {
                len = params[signature->params[i].length_idx];
                arr = mono_array_new(mono_domain_get(), mono_get_int32_class(),
                    len);

                if (len > 0) {
                    cell* addr = NULL;
                    amx_GetAddr(amx, params[i + 1], &addr);

                    for (int i = 0; i < len; i++) {
                        mono_array_set(arr, bool, i, !!*(addr + i));
                    }
                }
                args[i] = arr;
                break;
            }
            default:
                logprintf("[SampSharp] ERROR: Signature of %s contains "
                    "unsupported parameters.", name);
                return;
            }
Ejemplo n.º 12
0
bool GameMode::Load(std::string namespaceName, std::string className) {
    if (isLoaded_) {
        return false;
    }

    assert(MonoRuntime::IsLoaded());

    /* Build paths based on the specified namespace and class names. */
    string dirPath = PathUtil::GetPathInBin("gamemode/");
    string libraryPath = PathUtil::GetPathInBin("gamemode/")
        .append(namespaceName).append(".dll");
    string configPath = PathUtil::GetPathInBin("gamemode/")
        .append(namespaceName).append(".dll.config");

    /* Check for existance of game mode */
    std::ifstream ifile(libraryPath.c_str());
    if (!ifile) {
        logprintf("ERROR: library does not exist!");
        return false;
    }

    mono_domain_set_config(mono_domain_get(), dirPath.c_str(),
        configPath.c_str());

    domain_ = mono_domain_get();
    gameMode_.image = mono_assembly_get_image(
        mono_assembly_open(libraryPath.c_str(), NULL));

    if (!gameMode_.image) {
        logprintf("ERROR: Couldn't open image!");
        return false;
    }

    gameMode_.klass = mono_class_from_name(gameMode_.image,
        namespaceName.c_str(), className.c_str());

    if (!gameMode_.klass) {
        logprintf("ERROR: Couldn't find class %s:%s!",
            namespaceName.c_str(), className.c_str());
        return false;
    }

    baseMode_.klass = mono_class_get_parent(gameMode_.klass);

    if (!baseMode_.klass || strcmp("BaseMode",
        mono_class_get_name(baseMode_.klass)) != 0) {
        logprintf("ERROR: Parent type of %s::%s is not BaseMode!",
            namespaceName.c_str(), className.c_str());
        return false;
    }

    baseMode_.image = mono_class_get_image(baseMode_.klass);

    /* Add all internal calls. */
    AddInternalCall("RegisterExtension", (void *)RegisterExtension);
    AddInternalCall("SetTimer", (void *)SetRefTimer);
    AddInternalCall("KillTimer", (void *)KillRefTimer);
    AddInternalCall("NativeExists", (void *)NativeExists);
    AddInternalCall("LoadNative", (void *)LoadNative);
    AddInternalCall("InvokeNative", (void *)InvokeNative);
    AddInternalCall("Print", (void *)Print);
    AddInternalCall("SetCodepage", (void *)set_codepage);

    MonoObject *gamemode_obj = mono_object_new
        (mono_domain_get(), gameMode_.klass);
    gameModeHandle_ = mono_gchandle_new(gamemode_obj, false);
    mono_runtime_object_init(gamemode_obj);

    MonoMethod *method = LoadEvent("Initialize", 0);

    if (method) {
        MonoObject *exception = NULL;
        CallEvent(method, gameModeHandle_, NULL, &exception);

        return isLoaded_ = !exception;
    }
    else {
        isLoaded_ = true;
        return true;
    }
}
Ejemplo n.º 13
0
bool GameMode::Unload() {
    if (!isLoaded_) {
        return false;
    }

    /* Clear found methods. */
    tickMethod_ = NULL;
    paramLengthClass_ = NULL;
    paramLengthGetMethod_ = NULL;
    onCallbackException_ = NULL;

    /* Clear timers. */
    logprintf("Stopping timers...");
    for (TimerMap::iterator iter = timers_.begin();
        iter != timers_.end(); iter++) {
        int id = iter->first;
        RefTimer timer = (iter->second);

        mono_gchandle_free(timer.handle);
        KillTimer(id);
    }
    timers_.clear();

    /* Clear extensions. */
    logprintf("Unloading extensions...");
    for (ExtensionList::iterator iter = extensions_.begin();
        iter != extensions_.end(); iter++) {
        mono_gchandle_free(*iter);
    }
    extensions_.clear();

    /* Clear callbacks. */
    logprintf("Clearing callbacks table...");
    for (CallbackMap::iterator iter = callbacks_.begin();
        iter != callbacks_.end(); iter++) {
        iter->second->params.clear();
        delete iter->second;
    }
    callbacks_.clear();

    /* Dispose of game mode. */
    mono_thread_attach(domain_);

    MonoMethod *method = LoadEvent("Dispose", 0);

    if (method) {
        logprintf("Disposing gamemode...");
        CallEvent(method, gameModeHandle_, NULL, NULL);
    }

    /* Release game mode. */
    mono_gchandle_free(gameModeHandle_);

    gameModeHandle_ = NULL;

    /* TODO: For now, I see no way of unloading and reloading images without problems.
     * Best to look at this again in the future.
     */
    //mono_image_close(gameMode_.image);
    //mono_image_close(baseMode_.image);

    //mono_images_cleanup();

    gameMode_.image = NULL;
    gameMode_.klass = NULL;

    baseMode_.image = NULL;
    baseMode_.klass = NULL;

    domain_ = NULL;

    isLoaded_ = false;
    return true;
}