[Plugin] McRainbow r2 UPDATED
#11
Thanks for getting around to an update, hopefully this version doesn't have crashes and issues like v1.

STR, for now you can edit the files yourself or simply choose one plugin to load before the other, whichever you prefer.
Reply
Thanks given by:
#12
(12-29-2011, 07:02 AM)STR_Warrior Wrote: the /i and /item has an conflict with core.lua

I can see that /gm should conflict with the most recent core.lua but there is neither /i nor /item in mcrainbow.

I suspect further plugin treachery but I would start by removing /gm from mcrainbow and getting the most recent core.lua from *link*. I wasn't able to confirm this conflict on my test server so I'm shooting blind here.
Reply
Thanks given by:
#13
Rainbow 
I've fixed that for compatibility (just changed GetWorld() to GetDefaultWorld())
All credits to Ronald McDonald now! Wink

WARNING! It wasn't tested! So if all your data accidently got removed - I'm not responsible for that Smile


Attached Files
.lua   mcrainbowr2.lua (Size: 22.44 KB / Downloads: 276)
Reply
Thanks given by:
#14
eh i don't see it in the pluginlist when i do /pluginlist :S
oh wait i just had to restart
Reply
Thanks given by:
#15
mcrainbow still doestn't work verry well. Sad if there was a plugin that only is for the weather.
Reply
Thanks given by:
#16
I changed the deprecated World:GetAllPlayers() method with World:ForEachPlayer().
(Sorry for my defective English Blush )


Attached Files
.lua   mcrainbowr2.lua (Size: 22.71 KB / Downloads: 283)
Reply
Thanks given by:
#17
batekman, welcome to the forums. You seem to have a good grasp of Lua if you managed to spot how things are done Smile

Your change probably works okay most of the time, but there's a potential for it to crash the server:
The point of ForEachPlayer() callback mechanism is to force Lua plugins not to handle cPlayer instances anywhere else than in the callback. Imagine this situation:
Your plugin enumerates all players in the world (getPlayerByName() function). But just as this function is about to return the player object, another thread detects that the player has just disconnected, and removes the player from the world. Now Lua has an invalid cPlayer object, but doesn't know it, and as soon as the plugin tries to call a method on this object, the server crashes.

The Correct Way to handle this is to write a small handler function for each action that should be done with the found player, for example:
Code:
function HandleKill(Split, InitiatorPlayer)
    -- InitiatorPlayer is valid throughout this function, even within the local function KillSpecificPlayer()
    local World = cRoot:Get():GetDefaultWorld()
    local HasFound = false
    local PlayerName = Split[2]

    local KillSpecificPlayer = function(Player)
        -- Player is valid only within this callback, it cannot be saved and later used outside of this function!
        if (Player:GetName() == PlayerName) then
            Player:TakeDamage(100, InitiatorPlayer)
            HasFound = true
            return true
        end
    end
    World:ForEachPlayer(KillSpecificPlayer)

    if (!HasFound) then
        InitiatorPlayer:SendMessage(cChatColor.Green .. "Could not find player " .. Split[2])
    end
end
(note that I didn't try this code out, it's possibly slightly syntactically wrong, it's only to illustrate the approach)

I think I'll add a cWorld:DoWithPlayer(PlayerName, Callback) function later, that would call the callback only for the player of the specified name, so that the callback function can really do only the core minimum that it needs to do. Probably later Wink
Reply
Thanks given by:
#18
So I added the DoWithPlayer() function in Rev 639, here's an actual code that kills a player specified:
Code:
function HandleKill(Split, InitiatorPlayer)
    -- InitiatorPlayer is valid throughout this function, even within the local function KillPlayer()
    local World = cRoot:Get():GetDefaultWorld()
    local PlayerName = Split[2] or ""
    if (PlayerName == "") then
        InitiatorPlayer:SendMessage(cChatColor.Green .. "Expected the player name to kill as the parameter")
        return true
    end

    local KillPlayer = function(Player)
        -- Player is valid only within this function, it cannot be stord and used later!
        Player:SendMessage("Incoming gift from " .. InitiatorPlayer:GetName() .. " to " .. PlayerName .. ": " .. (Split[3] or ""))
        Player:TakeDamage(100, InitiatorPlayer)
        HasFound = true
    end
    if (not(World:DoWithPlayer(PlayerName, KillPlayer))) then
        InitiatorPlayer:SendMessage(cChatColor.Green .. "Could not find player " .. PlayerName)
    end
    return true
end
Reply
Thanks given by:
#19
doesn't work on r1024
Reply
Thanks given by:




Users browsing this thread: 1 Guest(s)