Phil25 / RTD

Roll The Dice SourceMod plugin for Team Fortress 2
GNU General Public License v3.0
56 stars 20 forks source link

Add a note to plugin developers/authors to recompile their plugins when updating the RTD plugin #105

Closed naydef closed 6 months ago

naydef commented 6 months ago

I usually expect that when updating plugins that those plugins will keep compatibility when using their API, however this isn't the case here:

L 02/29/2024 - 13:19:53: [SM] Exception reported: Invalid parameter number: 4
L 02/29/2024 - 13:19:53: [SM] Blaming: Gameplay/RTD/rtd.smx
L 02/29/2024 - 13:19:53: [SM] Call stack trace:
L 02/29/2024 - 13:19:53: [SM]   [0] GetNativeCell
L 02/29/2024 - 13:19:53: [SM]   [1] Line 308, rtd/natives.sp::Native_Remove
L 02/29/2024 - 13:19:53: [SM]   [3] RTD2_Remove
L 02/29/2024 - 13:19:53: [SM]   [4] Line 2377, tf2utils::cancelRTDRoll

The code failing: RTD2_Remove(client, RTDRemove_Custom, "Chaos Dice was used");

The plugin which relies on RTD was compiled with old include file, so It didn't have the new arguments the prototype. So I guess what I say is either keep backward compatibility or add a note for plugin devs/server owners to recompile their plugins which use RTD plugin when they update it.

That's all.

Phil25 commented 6 months ago

This was an oversight on my part. Update 2.5.2 introduced additional parameters which had default values, so no code change is required when recompiling plugins, but RTD didn't account for them not being provided at all.

I will release an update in a bit that will allow use of plugins compiled with pre-2.5.2 include file. You can fix this yourself for the time being by changing the Native_Remove function like this (untested):

public int Native_Remove(Handle hPlugin, int iParams)
{
    int client = GetNativeCell(1);
    RTDRemoveReason iReason = view_as<RTDRemoveReason>(GetNativeCell(2));
    char sReason[32];

    if (iReason == RTDRemove_Custom)
        GetNativeString(3, sReason, sizeof(sReason));

-   if (!GetNativeCell(4)) // not forced
+   if (iParams >= 4 && !GetNativeCell(4)) // not forced
    {
        Perk perk = RemovePerk(client, iReason, sReason);
        return perk ? perk.Id : -1;
    }

-   int iInitiator = GetNativeCell(5);
+   int iInitiator = iParams >= 5 ? GetNativeCell(5) : 0;
    if (IsValidClient(iInitiator) && g_hRollers.GetInRoll(client) && GetForwardFunctionCount(g_hFwdCanRemove) > 0)
    {
        Call_StartForward(g_hFwdCanRemove);
        Call_PushCell(iInitiator);
        Call_PushCell(client);
        Call_PushCell(g_hRollers.GetPerk(client).Id);

        Action result = Plugin_Continue;
        Call_Finish(result);

        if (result != Plugin_Continue)
            return -1;
    }

    Perk perk = ForceRemovePerk(client, iReason, sReason, iInitiator);
    return perk ? perk.Id : -1;
}

Plugins compiled with 2.X.X version of RTD should work with any higher 2.X.X version, period. I'm sorry for introducing this bug.

Phil25 commented 6 months ago

Tested and fixed in 2.5.4.