Snippet No Leavers

Romek

Super Moderator
Reaction score
963
No Leavers
By Romek

Introduction
I'm sure nearly everyone here has been in a game which has been completely ruined by some idiot leaving for no reason, and 9 players following him... :rolleyes:
This was actually inspired by people leaving!

Well, now there's a solution. "No Leavers" stops players leaving by nearly any means possible, reducing the chances of people not being able to play your map because of leavers.

Pros:
  • Stops players leaving in nearly every possible way.
  • If the player does leave, they'll most likely have to close wc3.

Cons:
  • Disables the Quest and Log menus.
  • A Player can still leave if they have a way of pressing keys quickly (Such as a Gamers Keyboard with Macro Buttons) or by using CTRL + ALT + DEL.

The Code:
JASS:
//                        -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//                        -=-=-= No Leavers Function by Romek V1.5 =-=-=- 
// +-----------------=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-----------------------------+ 
// |                            >> REQUIRES A vJASS PREPROCESSER <<                                      |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= How to Use: =-=-                                                                               |
// |  - Create a new trigger or copy the Snippet into the map header                                     |
// |  - Change the Global REFRESH_TIME to whatever you want. 0.025 recommended =]                        |
// |  - Change the function "Exceptions" to whatever you need (If GetFilterPlayer() == true, then        |
// |    that player won't get effected)                                                                  |
// |  - The system can be Turned on/off by Enabling and Disabling the trigger "NoLeavers_T"              |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= How to Edit the Exceptions Function: =-=-                                                      |
// |  - Remove "False"                                                                                   |
// |  - Add a player related condition such as: "GetPlayerName(GetFilterPlayer()) == Romek"              |
// |  - GetFilterPlayer() is the Player the condition applies to. Don't change it.                       |
// |  - In this case, It won't effect a player named "Romek"                                             |
// |  - To add multiple conditions, add "or" between the conditions.                                     |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= PROS: =-=-                                                                                     |
// |  - Stops any player leaving using nearly any method                                                 |
// |  - Even if they do leave, They'll have to close Wc3                                                 |
// |                                                                                                     |
// | -=-= CONS: =-=-                                                                                     |
// |  - Disables the Quests and Log menus                                                                |
// |  - Players can leave using CTRL + ALT + DELETE or if they have a method of pressing keys            |
// |    extremely quickly (Such as a Gamers Keyboard with Macro Keys)                                    |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= Changelog: =-=-                                                                                |
// |  - As this didn't work on the > majority < of games, it can now be used as a 'punishment' by        |
// |    setting the "PUNISH" variable to true. The ADMIN_PLAYER will then be able to use NL_PREFIX       |
// |    on/off to own a player =]                                                                        |
// +-----------------------------------------------------------------------------------------------------+
// | Credit isn't needed if used.                                                                        |
// +-----------------------------------------------------------------------------------------------------+
scope NoLeave initializer Init
    globals
        private constant real REFRESH_TIME = 0.025 // Edit here to set the Refresh time. Higher = MoreLag + Less Chances of Leaving
        
        private constant boolean PUNISH = true // Set to true to make this a punishment.
        private constant player ADMIN_PLAYER = Player(0) // This is the player which can use the "-noleave" commands
        private constant string NL_PREFIX_ON = "punish" // This is the command ADMIN_PLAYER uses to stop a player leaving
        private constant string NL_PREFIX_OFF = "unpunish" // This is the command ADMIN_PLAYER uses to let a player leave again
        // Use NL_PREFIX_## 1 to Punish player 1 (red)
    endglobals
    
    private function Exceptions takes nothing returns boolean // The Exceptions
        return false
    endfunction
    
// +-----------------------------------------------------------------------------------------------------+ \\
// |           >>> DO NOT EDIT BEYOND THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING! <<<                   | \\                                                      |
// +-----------------------------------------------------------------------------------------------------+ \\
    
    globals
        private boolexpr BOOL
        private force NoLeavers = CreateForce()
        public trigger T = CreateTrigger()
    endglobals
    
    private function Refresh takes nothing returns nothing            
        if IsPlayerInForce(GetLocalPlayer(), NoLeavers) then
            call ForceUICancel()
        endif
    endfunction
    
    private function CheckString takes string s returns boolean
        if S2I(s)/S2I(s) != 1 then
            return false
        endif
        return true
    endfunction
    
    private function PunishedOn takes nothing returns nothing
        local integer l = StringLength(GetEventPlayerChatString())
        local integer le = StringLength(NL_PREFIX_ON) + 1
        local integer i
        
        if CheckString(SubString(GetEventPlayerChatString(), le , l)) == true then
            set i = S2I(SubString(GetEventPlayerChatString(), le , l)) - 1
        else
            return
        endif
        debug call BJDebugMsg("Punish")
        debug call BJDebugMsg(I2S(i))
        if IsPlayerInForce(Player(i), NoLeavers) == false and Player(i) != ADMIN_PLAYER then
            call ForceAddPlayer(NoLeavers, Player(i))
        endif
    endfunction
    
    private function PunishedOff takes nothing returns nothing
        local integer l = StringLength(GetEventPlayerChatString())
        local integer le = StringLength(NL_PREFIX_OFF) + 1
        local integer i
        
        if CheckString(SubString(GetEventPlayerChatString(), le , l)) == true then
            set i = S2I(SubString(GetEventPlayerChatString(), le , l)) - 1
        else
            return
        endif
        if IsPlayerInForce(Player(i), NoLeavers) and Player(i) != ADMIN_PLAYER then
            call ForceRemovePlayer(NoLeavers, Player(i))
        endif
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local trigger t2 = CreateTrigger()
        set BOOL = Filter(function Exceptions)
        set BOOL = Not(BOOL)
        call TriggerRegisterTimerEvent(T, REFRESH_TIME, true)
        call TriggerAddAction(T, function Refresh)
        
        if PUNISH == false then
            call ForceEnumPlayers(NoLeavers, BOOL)
            call DestroyBoolExpr(BOOL)
            call DestroyTrigger(t)
            set t = null
            call DestroyTrigger(t2)
            set t2 = null
        else
            call TriggerRegisterPlayerChatEvent(t, ADMIN_PLAYER, NL_PREFIX_ON, false)
            call TriggerAddAction(t, function PunishedOn)
            call TriggerRegisterPlayerChatEvent(t2, ADMIN_PLAYER, NL_PREFIX_OFF, false)
            call TriggerAddAction(t2, function PunishedOff)
        endif
    endfunction
endscope


The Old Code:
JASS:
//                        -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//                        -=-=-= No Leavers Function by Romek V1.0 =-=-=- 
// +-----------------=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-----------------------------+ 
// |                            >> REQUIRES A vJASS PREPROCESSER <<                                      |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= How to Use: =-=-                                                                               |
// |  - Create a new trigger or copy the Snippet into the map header                                     |
// |  - Change the Global REFRESH_TIME to whatever you want. 0.025 recommended =]                        |
// |  - Change the function "Exceptions" to whatever you need (If GetFilterPlayer() == true, then        |
// |    that player won't get effected)                                                                  |
// |  - The system can be Turned on/off by Enabling and Disabling the trigger "NoLeavers_T"              |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= How to Edit the Exceptions Function: =-=-                                                      |
// |  - Remove "False"                                                                                   |
// |  - Add a player related condition such as: "GetPlayerName(GetFilterPlayer()) == Romek"              |
// |  - GetFilterPlayer() is the Player the condition applies to. Don't change it.                       |
// |  - In this case, It won't effect a player named "Romek"                                             |
// |  - To add multiple conditions, add "or" between the conditions.                                     |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= PROS: =-=-                                                                                     |
// |  - Stops any player leaving using nearly any method                                                 |
// |  - Even if they do leave, They'll have to close Wc3                                                 |
// |                                                                                                     |
// | -=-= CONS: =-=-                                                                                     |
// |  - Disables the Quests and Log menus                                                                |
// |  - Players can leave using CTRL + ALT + DELETE or if they have a method of pressing keys            |
// |    extremely quickly (Such as a Gamers Keyboard with Macro Keys)                                    |
// +-----------------------------------------------------------------------------------------------------+
// | Credit isn't needed if used.                                                                        |
// +-----------------------------------------------------------------------------------------------------+
scope NoLeave initializer Init
    globals
        private constant real REFRESH_TIME = 0.025 // Edit here to set the Refresh time. Higher = MoreLag + Less Chances of Leaving
    endglobals
    
    private function Exceptions takes nothing returns boolean // The Exceptions
        return false
    endfunction
    
// +-----------------------------------------------------------------------------------------------------+ \\
// |           >>> DO NOT EDIT BEYOND THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING! <<<                   | \\                                                      |
// +-----------------------------------------------------------------------------------------------------+ \\
    
    globals
        private boolexpr BOOL
        private force NoLeavers = CreateForce()
        public trigger T = CreateTrigger()
    endglobals
    
    private function Refresh takes nothing returns nothing            
        if IsPlayerInForce(GetLocalPlayer(), NoLeavers) then
            call ForceUICancel()
        endif
    endfunction
    
    private function Init takes nothing returns nothing
        local boolexpr B
        set BOOL = Filter(function Exceptions)
        set B = Not(BOOL)
        call ForceEnumPlayers(NoLeavers, B)
        call TriggerRegisterTimerEvent(T, REFRESH_TIME, true)
        call TriggerAddAction(T, function Refresh)
        call DestroyBoolExpr(BOOL)
        call DestroyBoolExpr(B)
        set B = null
    endfunction
endscope

The Map:
Do you really need a map? It's so small and easy to import!
 

quraji

zap
Reaction score
144
I'm all for this kind of thing (check out my VoteOwn system ;)), but I think this would just piss people off. My system that I'm shamelessly plugging forces a player to close WC3 after they've been "owned", but it's through a voting process, it's not always there.

But, that's not the coder's responsibility is it? :thup:


Hmmm...I have a mind to make a really annoying map that plays sounds and swings the camera around and things like that. Then, put this in and go on B.Net and host as "DOTA new version!! PROS ONLY". Bound to catch a few..

Oh by the way, I think this would make a great compliment to my Talkative chat system, check it out..
 

Romek

Super Moderator
Reaction score
963
This is meant to annoy people (Who would otherwise annoy others by leaving)
You can always add a victory trigger to your map or something :p

Also, "Owning" completely isolates a player from playing.
You can play the map perfectly fine with this. (Except for quests)
 

quraji

zap
Reaction score
144
Also, "Owning" completely isolates a player from playing.
You can play the map perfectly fine with this. (Except for quests)

So you've seen it, eh? ;)
And you're right, but I was only comparing the two because they both take a certain amount of control away from the player. Yours prevents them from leaving, mine does the same, as well as preventing them from playing any further.

Let me explain what I meant by "pissed off", in a quote: "All the other players are idiots, I'm leaving to find a new game. What?! I can't leave?! This map sucks..." and this person never plays again. Of course, the reaction may be the opposite, I can't say for sure. Either way, nice little snippet :p

Note:
I would change "higher" to "smaller":
Code:
    globals
        private constant real REFRESH_TIME = 0.025 // Edit here to set the Refresh time. Higher = MoreLag + Less Chances of Leaving
    endglobals

Any further conversation should take place on B.Net using my Talkative chat system, I think. It would only be appropriate.
 

Romek

Super Moderator
Reaction score
963
So you've seen it, eh? ;)
And you're right, but I was only comparing the two because they both take a certain amount of control away from the player. Yours prevents them from leaving, mine does the same, as well as preventing them from playing any further.

Yeah. I read through the thread :)

Let me explain what I meant by "pissed off", in a quote: "All the other players are idiots, I'm leaving to find a new game. What?! I can't leave?! This map sucks..." and this person never plays again. Of course, the reaction may be the opposite, I can't say for sure. Either way, nice little snippet :p

Mm.. Maybe. Well, you don't HAVE to put this into your map!

Note:
I would change "higher" to "smaller":
Code:
    globals
        private constant real REFRESH_TIME = 0.025 // Edit here to set the Refresh time. Higher = MoreLag + Less Chances of Leaving
    endglobals

Ahh. Thanks.
Fixed.

Any further conversation should take place on B.Net using my Talkative chat system, I think. It would only be appropriate.

-_-"
 

quraji

zap
Reaction score
144
I know I suggested we should continue any further communication using my useful and awesome chat system (the Talkative chat system, check it out), but:

Mm.. Maybe. Well, you don't HAVE to put this into your map!

Yes, exactly! That's all you have to say to nay-sayers (I had a few nay-sayers commenting on my leet and uber VoteOwn system).
 

Romek

Super Moderator
Reaction score
963
I know I suggested we should continue any further communication using my useful and awesome chat system (the Talkative chat system, check it out),

I've seen it. :p
I suggest we talk (If it's on-topic) here, and if not, then over PM.

Yes, exactly! That's all you have to say to nay-sayers (I had a few nay-sayers commenting on my leet and uber VoteOwn system).

Well.. Maybe :p
 

quraji

zap
Reaction score
144
I've seen it. :p
I suggest we talk (If it's on-topic) here, and if not, then over PM.

I'm just doing some shameless plugging...I've just bumped my thread from about a month ago...it needs some help ;)
 

Draphoelix

It's not the wintercold that's killing me
Reaction score
132
Does this stop people from leaving completely? I mean, if the game is over or something, do you have to close your wc3 down too?
 

Romek

Super Moderator
Reaction score
963
I'm just doing some shameless plugging...I've just bumped my thread from about a month ago...it needs some help ;)

Oh.. Ok :p

Does this stop people from leaving completely? I mean, if the game is over or something, do you have to close your wc3 down too?

No. Only using the Menus.
Victory/Defeat conditions will still work.

Hmm.. I guess I should make it a global trigger so that it can be enabled / disabled :p

Will change ASAP.
Done :)
 

Draphoelix

It's not the wintercold that's killing me
Reaction score
132
What about games that doesn't use victory/defeat? I mean, some games are AoS, and then someone get disconnects etc. Then you're like "I'm not going to play 2v1, I go play another game", do you have to close your wc3 down and then restart i
 

Flare

Stops copies me!
Reaction score
662
This is meant to annoy people (Who would otherwise annoy others by leaving)
Taking after ol' quraji, eh? :D

Anyway, if/when someone does leave, you have the problem of

"omg leaver i rmk"
(5 minutes later once they realise that something isn't right :p)
"OMFG, DUM GAEM, I CNT LEAV WTF"

Nice idea, but the cons do outweight the pros (since you won't be able to prevent anyone leaving if there isn't anyone joining :rolleyes:)

"GetPlayerName(GetFilterPlayer()) == Romek"
:p Perhaps you could add a string array and an array setup (that, by default, sets 5 or so of the arrays to "") function to make it as simple as possible for name exceptions (which is pretty much all you're gonna name)
 

Romek

Super Moderator
Reaction score
963
Taking after ol' quraji, eh? :p

Anyway, if/when someone does leave, you have the problem of
This is meant to prevent that...

"omg leaver i rmk"
...
"OMFG, DUM GAEM, I CNT LEAV WTF"

Nice idea, but the cons do outweight the pros (since you won't be able to prevent anyone leaving if there isn't anyone joining :rolleyes:)

Well.. You can always disable the trigger Anyway :p
 

Flare

Stops copies me!
Reaction score
662
This is meant to prevent that...
But, as you said yourself, 'they' could have a gaming keyboard macro or just use CTRL-ALT-DEL (or, if they are fast enough, Alt F4 then X) or just switch off their PC if they can't figure out the other options

If it could be set up to something where a person could only leave under certain conditions (like, they can only say 'offensive' words X times in the game if they want to leave), then it'd be awesome (then everyone gets to leave and the annoying c*nt gets stuck on his own :D)
 

Kazuga

Let the game begin...
Reaction score
110
I have to say that I love it. This would do perfectly in the Warlock maps since people leave in the first round because they don't have the patience to wait for the other's to get done...
 

Artificial

Without Intelligence
Reaction score
326
I tested this out. It made me wonder if you did that yourself. ^__^

Well, first of all, with REFRESH_TIME being 0.025 I was unable to choose units. That kinda sucked.

I put it to 1.00, and then I was able to choose units. But when I trained a unit, it stopped (as ForceUICancel does the same as pressing cancel there, doesn't it?). Also when I tried to cast a targetable spell it canceled. The same with ordering the units to move (by first pressing M) or attack (by first pressing A). :p

The pros was that it indeed made it harder to leave. :D
 

Romek

Super Moderator
Reaction score
963
But, as you said yourself, 'they' could have a gaming keyboard macro or just use CTRL-ALT-DEL (or, if they are fast enough, Alt F4 then X) or just switch off their PC if they can't figure out the other options

If it could be set up to something where a person could only leave under certain conditions (like, they can only say 'offensive' words X times in the game if they want to leave), then it'd be awesome (then everyone gets to leave and the annoying c*nt gets stuck on his own :D)

Most people would rather simply kick people who are like that.
Code:
CUNT!
FUCKER!
FAGGOT!
WANKERS!
Code:
Game: You now have permission to leave

I have to say that I love it. This would do perfectly in the Warlock maps since people leave in the first round because they don't have the patience to wait for the other's to get done...

Yeah :p

I tested this out. It made me wonder if you did that yourself. ^__^

Well, first of all, with REFRESH_TIME being 0.025 I was unable to choose units. That kinda sucked.

I put it to 1.00, and then I was able to choose units. But when I trained a unit, it stopped (as ForceUICancel does the same as pressing cancel there, doesn't it?). Also when I tried to cast a targetable spell it canceled. The same with ordering the units to move (by first pressing M) or attack (by first pressing A). :p

The pros was that it indeed made it harder to leave. :D

Damn.. I didn't bother testing it with units.
I'll try adding a function or something which disables the trigger when a player orders a unit to do something :p
 

Romek

Super Moderator
Reaction score
963
Hmm.. This might as well be scrapped. I don't think there is a way of detecting when a player presses a "Button" (For a spell, or w/e)

I did try though :p

JASS:
//                        -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//                        -=-=-= No Leavers Function by Romek V1.2 =-=-=- 
// +-----------------=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-----------------------------+ 
// |                            >> REQUIRES A vJASS PREPROCESSER <<                                      |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= How to Use: =-=-                                                                               |
// |  - Create a new trigger or copy the Snippet into the map header                                     |
// |  - Change the Global REFRESH_TIME to whatever you want. 0.025 recommended =]                        |
// |  - Change the function "Exceptions" to whatever you need (If GetFilterPlayer() == true, then        |
// |    that player won't get effected)                                                                  |
// |  - The system can be Turned on/off by Enabling and Disabling the trigger "NoLeavers_T"              |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= How to Edit the Exceptions Function: =-=-                                                      |
// |  - Remove "False"                                                                                   |
// |  - Add a player related condition such as: "GetPlayerName(GetFilterPlayer()) == Romek"              |
// |  - GetFilterPlayer() is the Player the condition applies to. Don't change it.                       |
// |  - In this case, It won't effect a player named "Romek"                                             |
// |  - To add multiple conditions, add "or" between the conditions.                                     |
// +-----------------------------------------------------------------------------------------------------+
// | -=-= PROS: =-=-                                                                                     |
// |  - Stops any player leaving using nearly any method                                                 |
// |  - Even if they do leave, They'll have to close Wc3                                                 |
// |                                                                                                     |
// | -=-= CONS: =-=-                                                                                     |
// |  - Disables the Quests and Log menus                                                                |
// |  - Players can leave using CTRL + ALT + DELETE or if they have a method of pressing keys            |
// |    extremely quickly (Such as a Gamers Keyboard with Macro Keys)                                    |
// +-----------------------------------------------------------------------------------------------------+
// | Credit isn't needed if used.                                                                        |
// +-----------------------------------------------------------------------------------------------------+
scope NoLeave initializer Init
    globals
        private constant real REFRESH_TIME = 0.025 // Edit here to set the Refresh time. Higher = MoreLag + Less Chances of Leaving
    endglobals
    
    private function Exceptions takes nothing returns boolean // The Exceptions
        return false
    endfunction
    
// +-----------------------------------------------------------------------------------------------------+ \\
// |           >>> DO NOT EDIT BEYOND THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING! <<<                   | \\                                                      |
// +-----------------------------------------------------------------------------------------------------+ \\
    
    globals
        private boolexpr BOOL
        private boolexpr True
        private force NoLeavers = CreateForce()
        public trigger T = CreateTrigger()
        private trigger DisT = CreateTrigger()
    endglobals
    
    private function XprTrue takes nothing returns boolean
        return true
    endfunction
    
    private function Refresh takes nothing returns nothing            
        if IsPlayerInForce(GetLocalPlayer(), NoLeavers) then
            call ForceUICancel()
        endif
    endfunction
    
    private function Disable takes nothing returns nothing
        local player P = GetOwningPlayer(GetTriggerUnit())
        if GetLocalPlayer() == P then
            call DisableTrigger(T)
        endif
        if GetOrderTarget() != null then
            if GetLocalPlayer() == P then
                call EnableTrigger(DisT)
            endif
        elseif GetOrderTarget() == null then
            call TriggerSleepAction(0.1)
            call EnableTrigger(T)
        endif
    endfunction
    
    private function ReEnable takes nothing returns nothing
        call EnableTrigger(T)
    endfunction
    
    private function Init takes nothing returns nothing
        local boolexpr B
        local trigger trig = CreateTrigger()
        local integer i = 0
        set True = Filter(function XprTrue)
        set BOOL = Filter(function Exceptions)
        set B = Not(BOOL)
        loop
            call TriggerRegisterPlayerUnitEvent(trig, Player(i), EVENT_PLAYER_UNIT_ISSUED_ORDER, True)
            call TriggerRegisterPlayerUnitEvent(DisT, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, True)
            call TriggerRegisterPlayerUnitEvent(DisT, Player(i), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, True)
            call TriggerRegisterPlayerUnitEvent(DisT, Player(i), EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER, True)
            set i = i + 1
            exitwhen i > 11
        endloop
        call TriggerAddAction(DisT, function ReEnable)
        call ForceEnumPlayers(NoLeavers, B)
        call TriggerRegisterTimerEvent(T, REFRESH_TIME, true)
        call TriggerAddAction(T, function Refresh)
        call DestroyBoolExpr(BOOL)
        call DestroyBoolExpr(B)
        set B = null
    endfunction
endscope
 
General chit-chat
Help Users

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top