Thread Tools Display Modes
06/27/18, 06:04 PM   #1
ziggr
 
ziggr's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2014
Posts: 27
GuildDemote() loop --> Error 307 Kicked from Server

Even with a 5-second zo_callLater() delay between calls, attempting any automation of guild ranks leads to the dreaded kick from server for message spam, followed by "Error 307 Booted from server" for ten minutes.

Is this API even callable at all? If a 5-second delay still triggers the ban, I'm not about to attempt it again even with 10 seconds between calls. How does the UI itself avoid a ban (because I could certainly manually promote/demote more than 1 player every 5 seconds).

I've got a couple dozen promotions/demotions pending in my 500-member guild, and not about to spend hours doing them manually.

--Z

Lua Code:
  1. function ZZGuildRank.DoSome()
  2.     self = ZZGuildRank
  3.     local i = #self.queue
  4.     assert(0 < i)
  5.     local record_str  = table.remove(self.queue,i)
  6.     local w           = split(record_str, "\t")
  7.     local want_rank   = tonumber(w[1])
  8.     local player_name = w[2]
  9.     self:SetRank(player_name, want_rank, i)
  10.     self:DoSomeLater()
  11. end
  12.  
  13. function ZZGuildRank:DoSomeLater()
  14.     if #self.queue <= 0 then
  15.         d("ZZGuildRank: Done.")
  16.         return
  17.     end
  18.                     -- 500, 1000, even 5000 too fast!
  19.                     -- cause server kick, dreaded
  20.                     -- "Error 307 Booted from Server" 15-minute softban
  21.     zo_callLater(function() ZZGuildRank.DoSome() end, 10 * 1000)
  22. end
  23.  
  24.  
  25. function ZZGuildRank:SetRank(player_name, want_rank, queue_index)
  26.     local member_info = self.guild[player_name]
  27.     if not member_info then
  28.         d("ZZGuildRank: not a member:"..player_name)
  29.         return
  30.     end
  31.     if member_info.curr_rank_index == want_rank then
  32.         d("ZZGuildRank: already rank "..tostring(want_rank).." "..player_name)
  33.         return
  34.     end
  35.  
  36.     local step = 1
  37.     local func = GuildDemote
  38.     if want_rank < member_info.curr_rank_index then
  39.         step = -1
  40.         func = GuildPromote
  41.     end
  42.  
  43.     for rank = member_info.curr_rank_index+step, want_rank, step do
  44.         d(string.format("|ceeeeee%d: rank:%d %s|r",queue_index, rank, player_name))
  45.         func(GUILD_INDEX, player_name)
  46.     end
  47. end

Last edited by ziggr : 06/27/18 at 10:31 PM.
  Reply With Quote
06/28/18, 03:56 AM   #2
Hydra9268
 
Hydra9268's Avatar
AddOn Author - Click to view addons
Join Date: May 2018
Posts: 33
Can your addon run as a background process? Wouldn't it be better to set the interval to a time that won't trigger the 307?
  Reply With Quote
06/28/18, 05:22 AM   #3
sirinsidiator
 
sirinsidiator's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 1,567
You call promote/demote in a loop without any interval inbetween in your SetRank function. Every single of these calls is counted towards the command spam limit. You will have to isolate each call in order to not get kicked.
  Reply With Quote
06/28/18, 01:40 PM   #4
ziggr
 
ziggr's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2014
Posts: 27
Originally Posted by sirinsidiator View Post
You call promote/demote in a loop without any interval inbetween in your SetRank function. Every single of these calls is counted towards the command spam limit. You will have to isolate each call in order to not get kicked.
Oh yeah. Forgot about that loop. It's only 1-3 promotions/demotions per player, but yeah, that adds up.
Also, not shown here, I make ~500 GetGuildMemberInfo() calls, in a tight loop, before starting the zo_callLater() promote/demote sequence. Those calls probably count against the command spam limit, which means I'm starting on thin ice.

I'll add a big delay after the GetGuildMemberInfo() loop, and de-loop the promote/demote cycle.

And not test this until I'm done with my dailies, just in case I get another 10-minute time out. ^_^

Thank you for the code review and shared wisdom!

--- edit ---
Success!

1. Remove the 500x GetGuildMemberInfo() loop at the start. Replace with individual GetGuildMemberIndexFromDisplayName() + GetGuildMemberInfo() calls inside the zo_callLater() sequence.
2. Increase zo_callLater() delay to 10 seconds between each guild member's promotion/demotion. Took 900 seconds to get through 90 guildies.

Was still able to promote/demote in a for-loop for those few guildies who were moved 2 or 3 ranks.

--Z

Last edited by ziggr : 06/28/18 at 02:09 PM. Reason: Success!
  Reply With Quote
06/28/18, 02:20 PM   #5
sirinsidiator
 
sirinsidiator's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 1,567
GetGuildMemberInfo is not an issue since it just returns the info that you already have locally on the client. I call that quite liberally in my addons and never had any issues.

What does create issues are functions that need to communicate with the server (e.g. editing notes, changing ranks, inviting members). Unfortunately there is no documentation or api available to tell us how many calls are allowed for each function and which functions share the same limit. For example group map pings seem to run on a different counter than guild functions.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » GuildDemote() loop --> Error 307 Kicked from Server

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off