ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   General Authoring Discussion (https://www.esoui.com/forums/forumdisplay.php?f=174)
-   -   GuildDemote() loop --> Error 307 Kicked from Server (https://www.esoui.com/forums/showthread.php?t=7897)

ziggr 06/27/18 06:04 PM

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

Hydra9268 06/28/18 03:56 AM

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?

sirinsidiator 06/28/18 05:22 AM

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.

ziggr 06/28/18 01:40 PM

Quote:

Originally Posted by sirinsidiator (Post 35187)
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

sirinsidiator 06/28/18 02:20 PM

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.


All times are GMT -6. The time now is 07:12 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI