vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | gGroupCalendar_MessagePrefix0 = "GC2"; |
2 | gGroupCalendar_MessagePrefix = gGroupCalendar_MessagePrefix0.."/"; |
||
3 | |||
4 | gGroupCalendar_MessagePrefixLength = string.len(gGroupCalendar_MessagePrefix); |
||
5 | |||
6 | gGroupCalendar_Channel = |
||
7 | { |
||
8 | Name = nil, |
||
9 | NameLower = nil, |
||
10 | ID = nil, |
||
11 | Password = nil, |
||
12 | AutoPlayer = nil, |
||
13 | Status = "Disconnected", |
||
14 | StatusMessage = nil, |
||
15 | GotTooManyChannelsMessage = false, |
||
16 | }; |
||
17 | |||
18 | gGroupCalendar_Queue = |
||
19 | { |
||
20 | TasksDelay = 0, |
||
21 | TasksElapsed = 0, |
||
22 | Tasks = {}, |
||
23 | |||
24 | RequestsDelay = 0, |
||
25 | RequestsElapsed = 0, |
||
26 | Requests = {[1] = {}, [2] = {}}, |
||
27 | |||
28 | InboundDelay = 0, |
||
29 | InboundMessages = {}, |
||
30 | InboundLastSender = nil, |
||
31 | InboundTimeSinceLastMessage = 0, |
||
32 | |||
33 | OutboundDelay = 0, |
||
34 | OutboundMessages = {}, |
||
35 | OutboundTimeSinceLastMessage = 0, |
||
36 | |||
37 | DatabaseUpdates = {}, |
||
38 | RSVPUpdates = {}, |
||
39 | }; |
||
40 | |||
41 | gCalendarNetwork_UserTrustCache = |
||
42 | { |
||
43 | }; |
||
44 | |||
45 | gCalendarNetwork_RequestDelay = |
||
46 | { |
||
47 | Init = 120, |
||
48 | ShortInit = 5, |
||
49 | SelfUpdateRequest = 1, |
||
50 | ExternalUpdateRequest = 30, |
||
51 | OwnedNotices = 300, -- Allow time for updates to arrive before we'll start advertising databases |
||
52 | JoinChannel2 = 2, |
||
53 | OwnedUpdate = 3, |
||
54 | ProxyUpdateMin = 6, |
||
55 | ProxyUpdateRange = 4, |
||
56 | |||
57 | RFUMin = 1, |
||
58 | RFURange = 5, |
||
59 | |||
60 | OwnedNOURange = 2, |
||
61 | ProxyNOUMin = 6, |
||
62 | ProxyNOURange = 4, |
||
63 | |||
64 | InboundQueue = 0.2, |
||
65 | OutboundQueue = 0.2, |
||
66 | RequestQueue = 0.2, |
||
67 | |||
68 | -- Outbound queue delay 1 - 5 seconds |
||
69 | |||
70 | OutboundQueueGapMin = 1, -- Delay for after last inbound message was processed |
||
71 | OutboundQueueGapWidth = 4, -- Random delay after the min time |
||
72 | |||
73 | -- Request queue delay 1 - 5 seconds |
||
74 | |||
75 | RequestQueueGapMin = 1, -- Delay for after last inbound or outbound message was processed |
||
76 | RequestQueueGapWidth = 4, -- Random delay after the min time |
||
77 | |||
78 | GuildUpdateAutoConfig = 2, |
||
79 | |||
80 | CheckDatabaseTrust = 10, |
||
81 | GuildRosterUpdate = 1, |
||
82 | |||
83 | -- Maximum age for an update is two minutes |
||
84 | |||
85 | MaximumUpdateAge = 120, |
||
86 | }; |
||
87 | |||
88 | gGroupCalendar_EnableUpdates = false; -- Don't allow the user to send updates to any databases |
||
89 | -- until we're sure that his databases are up-to-date themselves |
||
90 | gGroupCalendar_EnableSelfUpdates = false; -- Don't allow the user to send updates for their own databases |
||
91 | -- until well after they're sure nobody has updates for them |
||
92 | |||
93 | function CalendarNetwork_GetChannelStatus() |
||
94 | return gGroupCalendar_Channel.Status; |
||
95 | end |
||
96 | |||
97 | function CalendarNetwork_SetChannel(pChannel, pPassword) |
||
98 | -- Leave the channel and return if the new channel is nil |
||
99 | |||
100 | if not pChannel then |
||
101 | CalendarNetwork_LeaveChannel(); |
||
102 | return true; |
||
103 | end |
||
104 | |||
105 | -- Just return if nothing is actually changing |
||
106 | |||
107 | if gGroupCalendar_Channel.Name |
||
108 | and strupper(gGroupCalendar_Channel.Name) == strupper(pChannel) |
||
109 | and gGroupCalendar_Channel.Password == pPassword |
||
110 | and gGroupCalendar_Channel.Status == "Connected" then |
||
111 | return false; -- return false to indicate that no change was made |
||
112 | end |
||
113 | |||
114 | -- Leave the old channel and join the new one |
||
115 | |||
116 | CalendarNetwork_LeaveChannel(); |
||
117 | |||
118 | return CalendarNetwork_JoinChannel(pChannel, pPassword); |
||
119 | end |
||
120 | |||
121 | function CalendarNetwork_JoinChannel(pChannelName, pPassword) |
||
122 | if not pChannelName |
||
123 | or pChannelName == "" |
||
124 | or gGroupCalendar_Channel.Disconnected then |
||
125 | return false; |
||
126 | end |
||
127 | |||
128 | -- There seems to be some sort of bug with passworded channels getting |
||
129 | -- screwed up if the UI is reloaded and the solution appears to be to |
||
130 | -- leave and re-join the channel. Therefore, the code below... |
||
131 | |||
132 | LeaveChannelByName(pChannelName); |
||
133 | CalendarNetwork_LeftChannel(); |
||
134 | |||
135 | CalendarNetwork_SetChannelStatus("Initializing"); |
||
136 | |||
137 | CalendarNetwork_QueueTask( |
||
138 | CalendarNetwork_JoinChannel2, |
||
139 | {mChannelName = pChannelName, mPassword = pPassword}, |
||
140 | gCalendarNetwork_RequestDelay.JoinChannel2, |
||
141 | "JOINCHANNEL2"); |
||
142 | |||
143 | return true; |
||
144 | end |
||
145 | |||
146 | function CalendarNetwork_JoinChannelFailed() |
||
147 | if gGroupCalendar_Channel.GotTooManyChannelsMessage then |
||
148 | CalendarNetwork_SetChannelStatus("Error", GroupCalendar_cTooManyChannels); |
||
149 | else |
||
150 | CalendarNetwork_SetChannelStatus("Error", GroupCalendar_cJoinChannelFailed); |
||
151 | end |
||
152 | end |
||
153 | |||
154 | function CalendarNetwork_LeftChannel() |
||
155 | gGroupCalendar_Channel.Name = nil; |
||
156 | gGroupCalendar_Channel.Password = nil; |
||
157 | gGroupCalendar_Channel.NameLower = nil; |
||
158 | gGroupCalendar_Channel.ID = nil; |
||
159 | |||
160 | CalendarNetwork_SetChannelStatus("Disconnected"); |
||
161 | end |
||
162 | |||
163 | function CalendarNetwork_SetChannelStatus(pStatus, pStatusMessage) |
||
164 | gGroupCalendar_Channel.Status = pStatus; |
||
165 | gGroupCalendar_Channel.StatusMessage = pStatusMessage; |
||
166 | |||
167 | GroupCalendar_ChannelChanged(); |
||
168 | end |
||
169 | |||
170 | function CalendarNetwork_SystemMessage(pMessage) |
||
171 | if pMessage == ERR_TOO_MANY_CHAT_CHANNELS then |
||
172 | gGroupCalendar_Channel.GotTooManyChannelsMessage = true; |
||
173 | |||
174 | if gGroupCalendar_Channel.Status == "Error" then |
||
175 | CalendarNetwork_SetChannelStatus("Error", pMessage); |
||
176 | end |
||
177 | elseif pMessage == INSTANCE_SAVED then |
||
178 | -- Fetch the raid info so the reset events can be logged on |
||
179 | -- the calendar |
||
180 | |||
181 | RequestRaidInfo(); |
||
182 | elseif pMessage == NO_RAID_INSTANCES_SAVED then |
||
183 | EventDatabase_RemoveSavedInstanceEvents(gGroupCalendar_UserDatabase); |
||
184 | elseif pMessage == RAID_INSTANCE_INFO_HDR then |
||
185 | -- Remove existing events since they will be replaced by new incoming info |
||
186 | |||
187 | EventDatabase_RemoveSavedInstanceEvents(gGroupCalendar_UserDatabase); |
||
188 | else |
||
189 | local vStartIndex, vEndIndex, vName, vID, vDays, vHours, vMinutes, vSeconds = string.find(pMessage, "(.+) %(ID=(%x+)%): (%d+)d (%d+)h (%d+)m (%d+)s"); |
||
190 | |||
191 | if vStartIndex then |
||
192 | -- Calculate the number of seconds until the instance resets |
||
193 | |||
194 | local vRemainingDateTime60 = tonumber(vDays) * gCalendarSecondsPerDay |
||
195 | + Calendar_ConvertHMSToTime60(tonumber(vHours), tonumber(vMinutes), tonumber(vSeconds)); |
||
196 | |||
197 | local vServerResetDate, vServerResetTime = Calendar_GetServerDateTimeFromSecondsOffset(vRemainingDateTime60); |
||
198 | |||
199 | EventDatabase_ScheduleSavedInstanceEvent(gGroupCalendar_UserDatabase, vName, vServerResetDate, vServerResetTime); |
||
200 | end |
||
201 | end |
||
202 | end |
||
203 | |||
204 | function CalendarNetwork_JoinChannel2(pParams) |
||
205 | if gGroupCalendar_Settings.DebugInit then |
||
206 | Calendar_DebugMessage("CalendarNetwork_JoinChannel: "..pParams.mChannelName); |
||
207 | end |
||
208 | |||
209 | gGroupCalendar_Channel.GotTooManyChannelsMessage = false; |
||
210 | gGroupCalendar_Channel.Name = pParams.mChannelName; |
||
211 | |||
212 | local vChannelName = GetChannelName(pParams.mChannelName); |
||
213 | local vZoneChannel; |
||
214 | local vChannelAlreadyExists = false; |
||
215 | |||
216 | if vChannelName and vChannelName ~= 0 then |
||
217 | if gGroupCalendar_Settings.DebugInit then |
||
218 | Calendar_DebugMessage("Found existing channel "..pParams.mChannelName.." ("..vChannelName..")"); |
||
219 | end |
||
220 | |||
221 | vChannelName = pParams.mChannelName; |
||
222 | vChannelAlreadyExists = true; |
||
223 | else |
||
224 | if gGroupCalendar_Settings.DebugInit then |
||
225 | Calendar_DebugMessage("Channel "..pParams.mChannelName.." not found ("..vChannelName..") joining channel..."); |
||
226 | end |
||
227 | |||
228 | vZoneChannel, vChannelName = JoinChannelByName(pParams.mChannelName, pParams.mPassword, DEFAULT_CHAT_FRAME:GetID()); |
||
229 | |||
230 | if not vZoneChannel then |
||
231 | CalendarNetwork_JoinChannelFailed(); |
||
232 | return false; |
||
233 | end |
||
234 | |||
235 | if not vChannelName then |
||
236 | vChannelName = pParams.mChannelName; |
||
237 | end |
||
238 | end |
||
239 | |||
240 | -- Remove the channel from the chat frame so the user doesn't |
||
241 | -- have to watch all that data comm. (if we're running debug |
||
242 | -- code then leave the setting alone) |
||
243 | |||
244 | ChatFrame_RemoveChannel(DEFAULT_CHAT_FRAME, pParams.mChannelName); |
||
245 | |||
246 | if gCalendar_DebugFrame then |
||
247 | ChatFrame_AddChannel(gCalendar_DebugFrame, pParams.mChannelName); |
||
248 | end |
||
249 | |||
250 | gGroupCalendar_Channel.Password = pParams.mPassword; |
||
251 | gGroupCalendar_Channel.NameLower = strlower(pParams.mChannelName); |
||
252 | gGroupCalendar_Channel.ID = GetChannelName(gGroupCalendar_Channel.Name); |
||
253 | |||
254 | if not gGroupCalendar_Channel.ID |
||
255 | or gGroupCalendar_Channel.ID == 0 then |
||
256 | gGroupCalendar_Channel.ID = nil; |
||
257 | |||
258 | CalendarNetwork_JoinChannelFailed(); |
||
259 | |||
260 | return false; |
||
261 | end |
||
262 | |||
263 | if vChannelAlreadyExists then |
||
264 | CalendarNetwork_JoinedChannel(); |
||
265 | end |
||
266 | |||
267 | return true; |
||
268 | end |
||
269 | |||
270 | function CalendarNetwork_LeaveChannel() |
||
271 | if gGroupCalendar_Channel.Name |
||
272 | and gGroupCalendar_Channel.ID |
||
273 | and gGroupCalendar_Channel.Status ~= "Suspended" then |
||
274 | LeaveChannelByName(gGroupCalendar_Channel.Name); |
||
275 | CalendarNetwork_LeftChannel(); |
||
276 | end |
||
277 | end |
||
278 | |||
279 | function CalendarNetwork_JoinedChannel() |
||
280 | CalendarNetwork_SetChannelStatus("Connected"); |
||
281 | |||
282 | if gGroupCalendar_Settings.DebugInit then |
||
283 | Calendar_DebugMessage("CalendarNetwork_JoinChannel succeeded channel "..gGroupCalendar_Channel.Name.." ID "..gGroupCalendar_Channel.ID); |
||
284 | end |
||
285 | |||
286 | -- Send update requests/notices |
||
287 | |||
288 | CalendarNetwork_QueueTask(CalendarNetwork_SendNotices, nil, gCalendarNetwork_RequestDelay.SelfUpdateRequest, "SELFUPDATE"); |
||
289 | end |
||
290 | |||
291 | function CalendarNetwork_ChannelNotice(pChannelMessage, pChannelName, pChannelID, pActualChannelName) |
||
292 | -- Decode the channel name if it's in the nn. <channel name> format |
||
293 | |||
294 | local vChannelName = pChannelName; |
||
295 | |||
296 | for vFoundNumber, vFoundName in string.gfind(pChannelName, "(%d)%. (.+)") do |
||
297 | vChannelName = vFoundName; |
||
298 | end |
||
299 | |||
300 | -- Just leave if it's not a channel we're interested in |
||
301 | |||
302 | local vIsDataChannel = strlower(vChannelName) == gGroupCalendar_Channel.NameLower; |
||
303 | |||
304 | -- |
||
305 | |||
306 | if pChannelMessage == "YOU_JOINED" then |
||
307 | -- If it's one of the system channels, then shorten the initialization |
||
308 | -- timer if one is present |
||
309 | |||
310 | if pChannelID == 1 then |
||
311 | CalendarNetwork_SystemChannelJoined(); |
||
312 | end |
||
313 | |||
314 | if not vIsDataChannel then |
||
315 | return; |
||
316 | end |
||
317 | |||
318 | if pChannelID > 0 then |
||
319 | CalendarNetwork_JoinedChannel(); |
||
320 | else |
||
321 | -- Joining failed |
||
322 | |||
323 | CalendarNetwork_JoinChannelFailed(); |
||
324 | end |
||
325 | |||
326 | elseif pChannelMessage == "YOU_LEFT" then |
||
327 | if not vIsDataChannel then |
||
328 | return; |
||
329 | end |
||
330 | |||
331 | if not gGroupCalendar_Channel.ID then |
||
332 | return; |
||
333 | end |
||
334 | |||
335 | CalendarNetwork_LeftChannel(); |
||
336 | |||
337 | elseif pChannelMessage == "WRONG_PASSWORD" then |
||
338 | if not vIsDataChannel then |
||
339 | return; |
||
340 | end |
||
341 | |||
342 | CalendarNetwork_SetChannelStatus("Error", GroupCalendar_cWrongPassword); |
||
343 | end |
||
344 | end |
||
345 | |||
346 | function CalendarNetwork_SuspendChannel() |
||
347 | if gGroupCalendar_Channel.Status == "Suspended" |
||
348 | or not gGroupCalendar_Channel.Name |
||
349 | or not gGroupCalendar_Channel.ID then |
||
350 | return; |
||
351 | end |
||
352 | |||
353 | LeaveChannelByName(gGroupCalendar_Channel.Name); |
||
354 | |||
355 | gGroupCalendar_Channel.ID = nil; |
||
356 | CalendarNetwork_SetChannelStatus("Suspended"); |
||
357 | end |
||
358 | |||
359 | function CalendarNetwork_ResumeChannel() |
||
360 | if not gGroupCalendar_Channel.Status ~= "Suspended" then |
||
361 | return; |
||
362 | end |
||
363 | |||
364 | JoinChannelByName(gGroupCalendar_Channel.Name, gGroupCalendar_Channel.Password, DEFAULT_CHAT_FRAME:GetID()); |
||
365 | gGroupCalendar_Channel.ID = GetChannelName(gGroupCalendar_Channel.Name); |
||
366 | |||
367 | ChatFrame_RemoveChannel(DEFAULT_CHAT_FRAME, gGroupCalendar_Channel.Name); |
||
368 | |||
369 | CalendarNetwork_SetChannelStatus("Connected"); |
||
370 | end |
||
371 | |||
372 | function CalendarNetwork_UnpackIndexedList(...) |
||
373 | local vList = {}; |
||
374 | |||
375 | for vIndex = 1, arg.n, 2 do |
||
376 | vList[tonumber(arg[vIndex])] = arg[vIndex + 1]; |
||
377 | end |
||
378 | |||
379 | return vList; |
||
380 | end |
||
381 | |||
382 | function CalendarNetwork_GetChannelList() |
||
383 | local vChannelList = CalendarNetwork_UnpackIndexedList(GetChannelList()); |
||
384 | |||
385 | return vChannelList; |
||
386 | end |
||
387 | |||
388 | function CalendarNetwork_CalendarLoaded() |
||
389 | -- Set up a deferred initialization |
||
390 | |||
391 | CalendarNetwork_SetChannelStatus("Starting"); |
||
392 | |||
393 | -- See if there are system channels yet and use |
||
394 | -- the shorter delay if there are |
||
395 | |||
396 | local vDelay = gCalendarNetwork_RequestDelay.Init; |
||
397 | |||
398 | local vChannelList = CalendarNetwork_GetChannelList(); |
||
399 | |||
400 | if vChannelList[1] then |
||
401 | vDelay = gCalendarNetwork_RequestDelay.ShortInit; |
||
402 | end |
||
403 | |||
404 | -- |
||
405 | |||
406 | CalendarNetwork_QueueTask(CalendarNetwork_Initialize, nil, vDelay, "INIT"); |
||
407 | end |
||
408 | |||
409 | function CalendarNetwork_SystemChannelJoined() |
||
410 | CalendarNetwork_SetTaskDelay("INIT", gCalendarNetwork_RequestDelay.ShortInit); |
||
411 | end |
||
412 | |||
413 | function CalendarNetwork_ProcessCommandString(pSender, pTrustLevel, pCommandString, pCurrentTimeStamp) |
||
414 | local vCommand = CalendarNetwork_ParseCommandString(pCommandString); |
||
415 | |||
416 | if not vCommand then |
||
417 | if gGroupCalendar_Settings.Debug then |
||
418 | Calendar_DebugMessage("ProcessCommandString: Couldn't parse ["..pSender.."]:"..pCommandString); |
||
419 | end |
||
420 | |||
421 | return false; |
||
422 | end |
||
423 | |||
424 | return CalendarNetwork_ProcessCommand(pSender, pTrustLevel, vCommand, pCurrentTimeStamp); |
||
425 | end |
||
426 | |||
427 | function CalendarNetwork_ProcessCommand(pSender, pTrustLevel, pCommand, pCurrentTimeStamp) |
||
428 | -- Age out old updates which haven't been seen in a while |
||
429 | |||
430 | local vMinimumUpdateTime = pCurrentTimeStamp - gCalendarNetwork_RequestDelay.MaximumUpdateAge; |
||
431 | |||
432 | CalendarNetwork_KillOldUpdates("DB", gGroupCalendar_Queue.DatabaseUpdates, vMinimumUpdateTime); |
||
433 | CalendarNetwork_KillOldUpdates("RAT", gGroupCalendar_Queue.RSVPUpdates, vMinimumUpdateTime); |
||
434 | |||
435 | -- |
||
436 | |||
437 | local vOpcode = pCommand[1].opcode; |
||
438 | local vOperands = pCommand[1].operands; |
||
439 | |||
440 | table.remove(pCommand, 1); |
||
441 | |||
442 | if vOpcode == "DB" then |
||
443 | local vUserName = vOperands[1]; |
||
444 | local vDatabaseID = tonumber(vOperands[2]); |
||
445 | local vRevision = tonumber(vOperands[3]); |
||
446 | local vAuthRevision = tonumber(vOperands[4]); |
||
447 | |||
448 | -- If the sender is using wildcards, fetch the path from |
||
449 | -- the update records |
||
450 | |||
451 | if vUserName == "*" then |
||
452 | local vDatabaseUpdate = CalendarNetwork_FindDatabaseUpdate(pSender); |
||
453 | |||
454 | if not vDatabaseUpdate then |
||
455 | return; |
||
456 | end |
||
457 | |||
458 | vUserName = vDatabaseUpdate.mUserName; |
||
459 | vDatabaseID = vDatabaseUpdate.mDatabaseID; |
||
460 | vRevision = vDatabaseUpdate.mRevision; |
||
461 | vAuthRevision = nil; |
||
462 | end |
||
463 | |||
464 | -- |
||
465 | |||
466 | if not vRevision then |
||
467 | vRevision = 0; |
||
468 | end |
||
469 | |||
470 | if CalendarTrust_UserIsTrusted(vUserName) then -- only accept databases for trusted users (or our own) |
||
471 | CalendarNetwork_ProcessDatabaseCommand(pSender, pTrustLevel, vUserName, vDatabaseID, vRevision, vAuthRevision, pCommand); |
||
472 | else |
||
473 | if gGroupCalendar_Settings.DebugTrust then |
||
474 | Calendar_DebugMessage("ChannelMessageReceived: User "..vUserName.." is not trusted for DB command"); |
||
475 | end |
||
476 | end |
||
477 | elseif vOpcode == "RAT" then |
||
478 | local vUserName = vOperands[1]; |
||
479 | local vDatabaseID = tonumber(vOperands[2]); |
||
480 | local vRevision = tonumber(vOperands[3]); |
||
481 | local vAuthRevision = tonumber(vOperands[4]); |
||
482 | |||
483 | -- If the sender is using wildcards, fetch the path from |
||
484 | -- the update records |
||
485 | |||
486 | if vUserName == "*" then |
||
487 | local vRSVPUpdate = CalendarNetwork_FindRSVPUpdate(pSender); |
||
488 | |||
489 | if not vRSVPUpdate then |
||
490 | return; |
||
491 | end |
||
492 | |||
493 | vUserName = vRSVPUpdate.mUserName; |
||
494 | vDatabaseID = vRSVPUpdate.mDatabaseID; |
||
495 | vRevision = vRSVPUpdate.mRevision; |
||
496 | vAuthRevision = nil; |
||
497 | end |
||
498 | |||
499 | -- |
||
500 | |||
501 | if not vRevision then |
||
502 | vRevision = 0; |
||
503 | end |
||
504 | |||
505 | if CalendarTrust_UserIsTrustedForRSVPs(vUserName) then -- only accept RSVP for trusted users (or our own) |
||
506 | CalendarNetwork_ProcessRSVPCommand(pSender, vUserName, vDatabaseID, vRevision, vAuthRevision, pCommand); |
||
507 | else |
||
508 | if gGroupCalendar_Settings.DebugTrust then |
||
509 | Calendar_DebugMessage("ChannelMessageReceived: User "..vUserName.." is not trusted for RAT command"); |
||
510 | end |
||
511 | end |
||
512 | elseif vOpcode == "GLD" then |
||
513 | local vGuildName = vOperands[1]; |
||
514 | local vMinRank = tonumber(vOperands[2]); |
||
515 | |||
516 | CalendarNetwork_ProcessGuildCommand(pSender, pTrustLevel, vGuildName, vMinRank, pCommand); |
||
517 | elseif vOpcode == "ALL" then |
||
518 | CalendarNetwork_ProcessAllCommand(pSender, pTrustLevel, pCommand); |
||
519 | elseif vOpcode == "VER" then |
||
520 | local vDatabase = EventDatabase_GetDatabase(pSender, true); |
||
521 | |||
522 | if vDatabase then |
||
523 | vDatabase.AddonVersion = vOperands[1]; |
||
524 | end |
||
525 | else |
||
526 | if gGroupCalendar_Settings.Debug then |
||
527 | Calendar_DebugMessage("ProcessCommand: Unknown opcode "..vOpcode); |
||
528 | end |
||
529 | end |
||
530 | end |
||
531 | |||
532 | function CalendarNetwork_ProcessChangesRFU(pChanges, pDatabaseTag, pPlayerOwned, pPriority, pUserName, pDatabaseID, pRevision, pAuthRevision) |
||
533 | if gGroupCalendar_Settings.DebugUpdates then |
||
534 | Calendar_DebugMessage(pDatabaseTag.." changes update requested for: "..pUserName..","..pRevision); |
||
535 | end |
||
536 | |||
537 | -- Cancel a queued RFU for the same database if it's redundant |
||
538 | |||
539 | CalendarNetwork_CancelRedundantRFURequest(pDatabaseTag, pUserName, pDatabaseID, pRevision) |
||
540 | |||
541 | -- Just bail out if we don't have the requested database |
||
542 | |||
543 | if not pChanges then |
||
544 | return; |
||
545 | end |
||
546 | |||
547 | -- Create the request |
||
548 | |||
549 | local vRequest; |
||
550 | local vFromRevision; |
||
551 | local vForceUpdate = false; |
||
552 | |||
553 | if pChanges.ID ~= pDatabaseID then |
||
554 | if pPlayerOwned |
||
555 | or pChanges.ID > pDatabaseID then |
||
556 | vFromRevision = 0; |
||
557 | vForceUpdate = true; |
||
558 | else |
||
559 | if gGroupCalendar_Settings.DebugUpdates then |
||
560 | Calendar_DebugMessage("Not sending "..pDatabaseTag.." update: Requested database isn't available for "..pUserName..","..pDatabaseID); |
||
561 | end |
||
562 | |||
563 | return; |
||
564 | end |
||
565 | else |
||
566 | if pPlayerOwned |
||
567 | and pAuthRevision |
||
568 | and pAuthRevision < pRevision then |
||
569 | vFromRevision = pAuthRevision; |
||
570 | else |
||
571 | vFromRevision = pRevision; |
||
572 | end |
||
573 | end |
||
574 | |||
575 | vRequest = CalendarNetwork_FindUPDRequest(pDatabaseTag, pUserName); |
||
576 | |||
577 | if vRequest then |
||
578 | if vFromRevision < vRequest.mRevision then |
||
579 | if gGroupCalendar_Settings.DebugUpdates then |
||
580 | Calendar_DebugMessage("Changing existing "..pDatabaseTag.." request to revision "..vFromRevision.." for "..pUserName); |
||
581 | end |
||
582 | |||
583 | vRequest.mRevision = vFromRevision; |
||
584 | else |
||
585 | if gGroupCalendar_Settings.DebugUpdates then |
||
586 | Calendar_DebugMessage("Existing request for "..pDatabaseTag.." "..pUserName..","..pRevision); |
||
587 | end |
||
588 | end |
||
589 | |||
590 | CalendarNetwork_SetRequestPriority(vRequest, pPriority); |
||
591 | elseif pChanges.Revision > vFromRevision |
||
592 | or vForceUpdate then |
||
593 | vRequest = {}; |
||
594 | |||
595 | vRequest.mOpcode = pDatabaseTag.."_UPD"; |
||
596 | vRequest.mUserName = pUserName; |
||
597 | vRequest.mDatabaseID = pChanges.ID; |
||
598 | vRequest.mRevision = vFromRevision; |
||
599 | |||
600 | -- Determine a delay |
||
601 | |||
602 | local vDelay; |
||
603 | |||
604 | if pPlayerOwned then |
||
605 | vDelay = gCalendarNetwork_RequestDelay.OwnedUpdate; |
||
606 | else |
||
607 | vDelay = gCalendarNetwork_RequestDelay.ProxyUpdateMin + math.random() * gCalendarNetwork_RequestDelay.ProxyUpdateRange; |
||
608 | end |
||
609 | |||
610 | CalendarNetwork_QueueRequest(vRequest, vDelay, pPriority); |
||
611 | end |
||
612 | end |
||
613 | |||
614 | function CalendarNetwork_GetDatabaseChanges(pUserName, pCreate) |
||
615 | local vDatabase = EventDatabase_GetDatabase(pUserName, pCreate); |
||
616 | |||
617 | if vDatabase then |
||
618 | return vDatabase, vDatabase.Changes, vDatabase.IsPlayerOwned; |
||
619 | else |
||
620 | return nil, nil, nil; |
||
621 | end |
||
622 | end |
||
623 | |||
624 | function CalendarNetwork_GetDatabaseRSVPChanges(pUserName, pCreate) |
||
625 | local vDatabase = EventDatabase_GetDatabase(pUserName, pCreate); |
||
626 | |||
627 | if vDatabase then |
||
628 | return vDatabase, vDatabase.RSVPs, vDatabase.IsPlayerOwned; |
||
629 | else |
||
630 | return nil, nil, nil; |
||
631 | end |
||
632 | end |
||
633 | |||
634 | function CalendarNetwork_ProcessDatabaseCommand(pSender, pTrustLevel, pUserName, pDatabaseID, pRevision, pAuthRevision, pCommand) |
||
635 | local vOpcode = pCommand[1].opcode; |
||
636 | local vOperands = pCommand[1].operands; |
||
637 | |||
638 | table.remove(pCommand, 1); |
||
639 | |||
640 | local vDatabase, vChanges, vIsPlayerOwned = CalendarNetwork_GetDatabaseChanges(pUserName, false); |
||
641 | local vIsThisPlayerOwned = vIsPlayerOwned and pUserName == gGroupCalendar_PlayerName; |
||
642 | |||
643 | if vOpcode ~= "RFU" |
||
644 | and vOpcode ~= "RFV" |
||
645 | and pTrustLevel < 2 then |
||
646 | -- Players with moderate trust levels (ie, fellow guild members) are |
||
647 | -- only allowed to requeust updates, not provide updates |
||
648 | |||
649 | if gGroupCalendar_Settings.DebugTrust then |
||
650 | Calendar_DebugMessage("CalendarNetwork_ProcessDatabaseCommand: Ignoring "..vOpcode.." request from "..pSender); |
||
651 | end |
||
652 | |||
653 | return; |
||
654 | end |
||
655 | |||
656 | if vOpcode == "RFU" then |
||
657 | -- If the sender is seen transmitting an RFU while he has a database update |
||
658 | -- pending then it probably means he d/c'd. Kill the database update in that |
||
659 | -- case |
||
660 | |||
661 | CalendarNetwork_KillSendersDatabaseUpdates(pSender); |
||
662 | |||
663 | -- |
||
664 | |||
665 | if vChanges then |
||
666 | -- Give the owner high-priority to help ensure that he can roam successfully |
||
667 | |||
668 | local vPriority; |
||
669 | |||
670 | if pSender == pUserName then |
||
671 | vPriority = 1; |
||
672 | else |
||
673 | vPriority = 2; |
||
674 | end |
||
675 | |||
676 | CalendarNetwork_ProcessChangesRFU(vChanges, "DB", vIsThisPlayerOwned, vPriority, pUserName, pDatabaseID, pRevision, pAuthRevision); |
||
677 | end |
||
678 | elseif vOpcode == "RFV" then |
||
679 | -- If the sender is seen transmitting an RFV while he has a database update |
||
680 | -- pending then it probably means he d/c'd. Kill the database update in that |
||
681 | -- case |
||
682 | |||
683 | CalendarNetwork_KillSendersDatabaseUpdates(pSender); |
||
684 | |||
685 | -- |
||
686 | |||
687 | if vIsThisPlayerOwned then |
||
688 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix.."VER:"..gGroupCalendar_VersionString); |
||
689 | end |
||
690 | elseif vOpcode == "NOU" then |
||
691 | -- If the sender is seen transmitting an NOU while he has a database update |
||
692 | -- pending then it probably means he d/c'd. Kill the database update in that |
||
693 | -- case |
||
694 | |||
695 | CalendarNetwork_KillSendersDatabaseUpdates(pSender); |
||
696 | |||
697 | -- |
||
698 | |||
699 | local vCurrentRevision = 0; |
||
700 | local vDatabaseIDChanged = false; |
||
701 | |||
702 | if not vIsThisPlayerOwned then |
||
703 | CalendarNetwork_CancelRedundantNOURequests(vChanges, "DB", pSender, pUserName, pDatabaseID, pRevision); |
||
704 | end |
||
705 | |||
706 | if not vDatabase then |
||
707 | vDatabase = EventDatabase_AssumeDatabase(pUserName); |
||
708 | end |
||
709 | |||
710 | if vDatabase then |
||
711 | -- Ignore external updates to our own databases |
||
712 | |||
713 | if vDatabase.IsPlayerOwned then |
||
714 | -- If someone sent out a NOU for one of our databases and it's older than |
||
715 | -- ours and ours is now empty, send out a DEL to let them know that it's newer |
||
716 | -- and empty now |
||
717 | |||
718 | if CalendarChanges_IsEmpty(vChanges) then |
||
719 | CalendarNetwork_SendEmptyChanges(vChanges, "DB", pUserName); |
||
720 | end |
||
721 | |||
722 | return; |
||
723 | end |
||
724 | |||
725 | -- Ignore the update if the ID is older than the one we have |
||
726 | -- unless it's from the owner |
||
727 | |||
728 | if vChanges |
||
729 | and pDatabaseID < vChanges.ID |
||
730 | and pSender ~= vDatabase.UserName then |
||
731 | return; |
||
732 | end |
||
733 | |||
734 | -- Force a RFU if the ID is changing |
||
735 | |||
736 | if not vChanges |
||
737 | or vChanges.ID ~= pDatabaseID then |
||
738 | vDatabaseIDChanged = true; |
||
739 | else |
||
740 | vCurrentRevision = vChanges.Revision; |
||
741 | |||
742 | if not vCurrentRevision then |
||
743 | Calendar_ErrorMessage("Changes for "..pUserName.." has nil revision"); |
||
744 | return; |
||
745 | end |
||
746 | end |
||
747 | end |
||
748 | |||
749 | if vDatabaseIDChanged |
||
750 | or vCurrentRevision < pRevision then |
||
751 | CalendarNetwork_QueueRFURequest(pUserName, "DB", pDatabaseID, pRevision); |
||
752 | end |
||
753 | elseif vOpcode == "UPD" then |
||
754 | -- If the sender is seen transmitting an UPD while he has another database update |
||
755 | -- pending then it probably means he d/c'd. Kill the database update in that |
||
756 | -- case |
||
757 | |||
758 | CalendarNetwork_KillSendersDatabaseUpdates(pSender, pUserName); |
||
759 | |||
760 | -- Begin a database update |
||
761 | |||
762 | local vSinceRevision = tonumber(vOperands[1]); |
||
763 | |||
764 | if not vSinceRevision then |
||
765 | if gGroupCalendar_Settings.DebugErrors then |
||
766 | Calendar_DebugMessage("GroupCalendar: DB UPD received from "..pSender.." for "..pUserName.." with no SinceRevision"); |
||
767 | end |
||
768 | |||
769 | return; |
||
770 | end |
||
771 | |||
772 | if not vIsThisPlayerOwned then |
||
773 | -- If we're waiting to request this same update, cancel the request |
||
774 | |||
775 | CalendarNetwork_CancelRedundantRFURequest("DB", pUserName, pDatabaseID, vSinceRevision); |
||
776 | |||
777 | -- If we're waiting to send this same update, cancel the request |
||
778 | |||
779 | CalendarNetwork_CancelRedundantUPDRequests(vChanges, "DB", pUserName, pDatabaseID, pRevision, vSinceRevision); |
||
780 | end |
||
781 | |||
782 | CalendarNetwork_BeginDatabaseUpdate(pSender, pUserName, pDatabaseID, pRevision, vSinceRevision); |
||
783 | |||
784 | elseif vOpcode == "DEL" then |
||
785 | -- Delete the database since it's empty |
||
786 | |||
787 | if not vIsThisPlayerOwned then |
||
788 | CalendarNetwork_CancelRedundantUPDRequests(vChanges, "DB", pUserName, pDatabaseID, pRevision, 0); |
||
789 | end |
||
790 | |||
791 | CalendarNetwork_DeleteDatabase(pSender, pUserName, pDatabaseID, pRevision); |
||
792 | |||
793 | elseif vOpcode == "EVT" then |
||
794 | -- Event data |
||
795 | |||
796 | local vEventID = tonumber(vOperands[1]); |
||
797 | |||
798 | CalendarNetwork_InsertEventUpdate(pSender, pUserName, pDatabaseID, pRevision, vEventID, pCommand); |
||
799 | |||
800 | elseif vOpcode == "END" then |
||
801 | -- End a database update |
||
802 | |||
803 | local vSinceRevision = tonumber(vOperands[1]); |
||
804 | |||
805 | CalendarNetwork_EndDatabaseUpdate(pSender, pUserName, pDatabaseID, pRevision, vSinceRevision); |
||
806 | end |
||
807 | end |
||
808 | |||
809 | function CalendarNetwork_ProcessRSVPCommand(pSender, pUserName, pDatabaseID, pRevision, pAuthRevision, pCommand) |
||
810 | local vOpcode = pCommand[1].opcode; |
||
811 | local vOperands = pCommand[1].operands; |
||
812 | local vOperandString = pCommand[1].operandString; |
||
813 | |||
814 | table.remove(pCommand, 1); |
||
815 | |||
816 | local vDatabase, vChanges, vIsPlayerOwned = CalendarNetwork_GetDatabaseRSVPChanges(pUserName, false); |
||
817 | local vIsThisPlayerOwned = vIsPlayerOwned and pUserName == gGroupCalendar_PlayerName; |
||
818 | |||
819 | if vOpcode == "RFU" then |
||
820 | -- If the sender is seen transmitting an RFU while he has a database update |
||
821 | -- pending then it probably means he d/c'd. Kill the database update in that |
||
822 | -- case |
||
823 | |||
824 | CalendarNetwork_KillSendersRSVPUpdates(pSender); |
||
825 | |||
826 | -- |
||
827 | |||
828 | if vChanges then |
||
829 | -- Give the owner high-priority to help ensure that he can roam successfully |
||
830 | |||
831 | local vPriority; |
||
832 | |||
833 | if pSender == pUserName then |
||
834 | vPriority = 1; |
||
835 | else |
||
836 | vPriority = 2; |
||
837 | end |
||
838 | |||
839 | CalendarNetwork_ProcessChangesRFU(vChanges, "RAT", vIsThisPlayerOwned, vPriority, pUserName, pDatabaseID, pRevision, pAuthRevision); |
||
840 | end |
||
841 | elseif vOpcode == "NOU" then |
||
842 | -- If the sender is seen transmitting a NOU while he has a database update |
||
843 | -- pending then it probably means he d/c'd. Kill the database update in that |
||
844 | -- case |
||
845 | |||
846 | CalendarNetwork_KillSendersRSVPUpdates(pSender); |
||
847 | |||
848 | -- |
||
849 | |||
850 | local vCurrentRevision = 0; |
||
851 | local vDatabaseIDChanged = false; |
||
852 | |||
853 | if not vIsThisPlayerOwned then |
||
854 | CalendarNetwork_CancelRedundantNOURequests(vChanges, "RAT", pSender, pUserName, pDatabaseID, pRevision); |
||
855 | end |
||
856 | |||
857 | if vDatabase then |
||
858 | -- Ignore external updates to our own databases |
||
859 | |||
860 | if vDatabase.IsPlayerOwned then |
||
861 | -- If someone sent out a NOU for one of our databases and it's older than |
||
862 | -- ours and ours is now empty, send out a DEL to let them know that it's newer |
||
863 | -- and empty now |
||
864 | |||
865 | if CalendarChanges_IsEmpty(vChanges) then |
||
866 | CalendarNetwork_SendEmptyChanges(vChanges, "RAT", pUserName); |
||
867 | end |
||
868 | |||
869 | return; |
||
870 | end |
||
871 | |||
872 | -- Ignore the update if the ID is older than the one we have |
||
873 | -- unless it's from the owner |
||
874 | |||
875 | if vChanges |
||
876 | and pDatabaseID < vChanges.ID |
||
877 | and pSender ~= vDatabase.UserName then |
||
878 | return; |
||
879 | end |
||
880 | |||
881 | -- Purge the existing database if the ID is changing |
||
882 | |||
883 | if not vChanges |
||
884 | or vChanges.ID ~= pDatabaseID then |
||
885 | vDatabaseIDChanged = true; |
||
886 | else |
||
887 | vCurrentRevision = vChanges.Revision; |
||
888 | end |
||
889 | end |
||
890 | |||
891 | if vDatabaseIDChanged |
||
892 | or vCurrentRevision < pRevision then |
||
893 | CalendarNetwork_QueueRFURequest(pUserName, "RAT", pDatabaseID, pRevision); |
||
894 | end |
||
895 | elseif vOpcode == "UPD" then |
||
896 | -- If the sender is seen transmitting an UPD while he has a database update |
||
897 | -- pending then it probably means he d/c'd. Kill the database update in that |
||
898 | -- case |
||
899 | |||
900 | CalendarNetwork_KillSendersRSVPUpdates(pSender, pUserName); |
||
901 | |||
902 | -- |
||
903 | |||
904 | -- Begin a RSVP database update |
||
905 | |||
906 | local vSinceRevision = tonumber(vOperands[1]); |
||
907 | |||
908 | if not vSinceRevision then |
||
909 | if gGroupCalendar_Settings.DebugErrors then |
||
910 | Calendar_DebugMessage("GroupCalendar: RAT UPD received from "..pSender.." for "..pUserName.." with no SinceRevision"); |
||
911 | end |
||
912 | |||
913 | return; |
||
914 | end |
||
915 | |||
916 | if not vIsThisPlayerOwned then |
||
917 | -- If we're waiting to ask for an update to this database, cancel the request |
||
918 | |||
919 | CalendarNetwork_CancelRedundantRFURequest("RAT", pUserName, pDatabaseID, vSinceRevision); |
||
920 | |||
921 | -- If we're waiting to send this same update, cancel the request |
||
922 | |||
923 | CalendarNetwork_CancelRedundantUPDRequests(vChanges, "RAT", pUserName, pDatabaseID, pRevision, vSinceRevision); |
||
924 | end |
||
925 | |||
926 | CalendarNetwork_BeginRSVPUpdate(pSender, pUserName, pDatabaseID, pRevision, vSinceRevision); |
||
927 | |||
928 | elseif vOpcode == "DEL" then |
||
929 | -- Delete the database since it's empty |
||
930 | |||
931 | if not vIsThisPlayerOwned then |
||
932 | CalendarNetwork_CancelRedundantUPDRequests(vChanges, "RAT", pUserName, pDatabaseID, pRevision, 0); |
||
933 | end |
||
934 | |||
935 | CalendarNetwork_DeleteRSVPs(pSender, pUserName, pDatabaseID, pRevision); |
||
936 | |||
937 | elseif vOpcode == "EVT" then |
||
938 | -- Event data |
||
939 | |||
940 | CalendarNetwork_InsertRSVPUpdate(pSender, pUserName, pDatabaseID, pRevision, vOperandString); |
||
941 | |||
942 | elseif vOpcode == "END" then |
||
943 | -- End a RSVP update |
||
944 | |||
945 | local vSinceRevision = tonumber(vOperands[1]); |
||
946 | |||
947 | CalendarNetwork_EndRSVPUpdate(pSender, pUserName, pDatabaseID, pRevision, vSinceRevision); |
||
948 | end |
||
949 | end |
||
950 | |||
951 | function CalendarNetwork_ProcessGuildCommand(pSender, pTrustLevel, pGuildName, pMinRank, pCommand) |
||
952 | -- Ignore guild commands if they're not directed at the player's guild |
||
953 | -- or not at the player's rank |
||
954 | |||
955 | if pGuildName ~= gGroupCalendar_PlayerGuild |
||
956 | or gGroupCalendar_PlayerGuildRank > pMinRank then |
||
957 | return; |
||
958 | end |
||
959 | |||
960 | -- Pass it on to the ALL handler for further processing |
||
961 | |||
962 | CalendarNetwork_ProcessAllCommand(pSender, pTrustLevel, pCommand); |
||
963 | end |
||
964 | |||
965 | function CalendarNetwork_ProcessAllCommand(pSender, pTrustLevel, pCommand) |
||
966 | local vOpcode = pCommand[1].opcode; |
||
967 | local vOperands = pCommand[1].operands; |
||
968 | |||
969 | table.remove(pCommand, 1); |
||
970 | |||
971 | if vOpcode == "RFU" then |
||
972 | CalendarNetwork_SendAllRevisionNotices(); |
||
973 | elseif vOpcode == "RFV" then |
||
974 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix.."VER:"..gGroupCalendar_VersionString); |
||
975 | end |
||
976 | end |
||
977 | |||
978 | function CalendarNetwork_DatabaseIsNewer(pDatabaseID1, pRevision1, pDatabaseID2, pRevision2) |
||
979 | if pDatabaseID2 > pDatabaseID1 then |
||
980 | return true; |
||
981 | elseif pDatabaseID2 < pDatabaseID1 then |
||
982 | return false; |
||
983 | else |
||
984 | return pRevision2 > pRevision1; |
||
985 | end |
||
986 | end |
||
987 | |||
988 | function CalendarNetwork_UpdateIsBetterThanOurs(pSender, pUserName, pDatabaseID, pRevision, pDatabase, pChanges) |
||
989 | -- Updates for our own databases are always worse if |
||
990 | -- we're on the toon |
||
991 | |||
992 | if pDatabase.IsPlayerOwned and pUserName == gGroupCalendar_PlayerName then |
||
993 | return false; |
||
994 | end |
||
995 | |||
996 | -- Updates from the owner are always better than ours |
||
997 | -- as are updates when our list is empty |
||
998 | |||
999 | if string.lower(pSender) == string.lower(pUserName) |
||
1000 | or not pChanges then |
||
1001 | return true; |
||
1002 | end |
||
1003 | |||
1004 | -- If the revision is higher than what we have it's better |
||
1005 | |||
1006 | return CalendarNetwork_DatabaseIsNewer(pChanges.ID, pChanges.Revision, pDatabaseID, pRevision); |
||
1007 | end |
||
1008 | |||
1009 | function CalendarNetwork_DeleteDatabase(pSender, pUserName, pDatabaseID, pRevision) |
||
1010 | -- Get the database |
||
1011 | |||
1012 | local vDatabase = EventDatabase_GetDatabase(pUserName, false); |
||
1013 | |||
1014 | -- Nothing to do if we don't even have the database |
||
1015 | |||
1016 | if not vDatabase then |
||
1017 | return; |
||
1018 | end |
||
1019 | |||
1020 | -- Bail out if our stuff is better |
||
1021 | |||
1022 | if not CalendarNetwork_UpdateIsBetterThanOurs(pSender, pUserName, pDatabaseID, pRevision, vDatabase, vDatabase.Changes) then |
||
1023 | return; |
||
1024 | end |
||
1025 | |||
1026 | -- Empty the specified changelist |
||
1027 | |||
1028 | EventDatabase_PurgeDatabase(vDatabase, pDatabaseID); |
||
1029 | vDatabase.Changes.Revision = pRevision; |
||
1030 | end |
||
1031 | |||
1032 | function CalendarNetwork_BeginDatabaseUpdate(pSender, pUserName, pDatabaseID, pRevision, pSinceRevision) |
||
1033 | -- If the same sender has a pending update already in progress, kill it |
||
1034 | |||
1035 | CalendarNetwork_KillSendersDatabaseUpdates(pSender, pUserName); |
||
1036 | |||
1037 | -- Get the database |
||
1038 | |||
1039 | local vDatabase = EventDatabase_GetDatabase(pUserName, false); |
||
1040 | |||
1041 | -- Ignore updates for our own databases |
||
1042 | |||
1043 | if vDatabase |
||
1044 | and vDatabase.IsPlayerOwned |
||
1045 | and not gGroupCalendar_Settings.AllowSelfUpdate then |
||
1046 | return; |
||
1047 | end |
||
1048 | |||
1049 | local vChanges; |
||
1050 | |||
1051 | if vDatabase then |
||
1052 | vChanges = vDatabase.Changes; |
||
1053 | else |
||
1054 | vChanges = nil; |
||
1055 | end |
||
1056 | |||
1057 | -- Ignore the update if it isn't from the owner and |
||
1058 | -- our database ID is newer |
||
1059 | |||
1060 | if string.lower(pSender) ~= string.lower(pUserName) |
||
1061 | and vChanges then |
||
1062 | if (vChanges.ID > pDatabaseID) |
||
1063 | or (vChanges.ID == pDatabaseID |
||
1064 | and vChanges.Revision >= pRevision) then |
||
1065 | return; |
||
1066 | end |
||
1067 | end |
||
1068 | |||
1069 | -- If it's from the owner and isn't the same revision as ours, |
||
1070 | -- then delete the database. If the update is from revision |
||
1071 | -- zero go ahead with the update otherwise ignore it and request |
||
1072 | -- and update from zero |
||
1073 | |||
1074 | if string.lower(pSender) == string.lower(pUserName) |
||
1075 | and vChanges |
||
1076 | and vChanges.ID ~= pDatabaseID then |
||
1077 | EventDatabase_PurgeDatabase(vDatabase, pDatabaseID); |
||
1078 | |||
1079 | if pSinceRevision ~= 0 then |
||
1080 | -- Request an update and exit |
||
1081 | |||
1082 | CalendarNetwork_QueueRFURequest(pUserName, "DB", pDatabaseID, 0) |
||
1083 | return; |
||
1084 | end |
||
1085 | end |
||
1086 | |||
1087 | -- See if there's another update for the same database already in progress |
||
1088 | |||
1089 | local vDatabaseUpdate = CalendarNetwork_FindDatabaseUpdate(nil, pUserName, nil); |
||
1090 | |||
1091 | if vDatabaseUpdate then |
||
1092 | -- If the new update is from the owner or |
||
1093 | -- the old one isn't from the owner and is a higher revision, |
||
1094 | -- then cancel the old update |
||
1095 | |||
1096 | if string.lower(pSender) == string.lower(pUserName) |
||
1097 | or (vDatabaseUpdate.mSender ~= vDatabaseUpdate.mUserName |
||
1098 | and CalendarNetwork_DatabaseIsNewer(vDatabaseUpdate.mDatabaseID, vDatabaseUpdate.mRevision, pDatabaseID, pRevision)) then |
||
1099 | CalendarNetwork_CancelDatabaseUpdate(nil, pUserName, nil); |
||
1100 | |||
1101 | -- Otherwise cancel this one |
||
1102 | |||
1103 | else |
||
1104 | return; |
||
1105 | end |
||
1106 | end |
||
1107 | |||
1108 | if gGroupCalendar_Settings.DebugUpdates then |
||
1109 | Calendar_DebugMessage("CalendarNetwork_BeginDatabaseUpdate: "..pUserName..","..pRevision.." since revision "..pSinceRevision.." from "..pSender); |
||
1110 | end |
||
1111 | |||
1112 | -- Can't accept updates which don't cover the last revision we received |
||
1113 | |||
1114 | if vChanges |
||
1115 | and pSinceRevision > vChanges.Revision then |
||
1116 | -- Ask for another copy of the update starting with the revision we need |
||
1117 | |||
1118 | CalendarNetwork_QueueRFURequest(pUserName, "DB", pDatabaseID, vChanges.Revision) |
||
1119 | return; |
||
1120 | end |
||
1121 | |||
1122 | -- Create the database update record |
||
1123 | |||
1124 | vDatabaseUpdate = {}; |
||
1125 | |||
1126 | vDatabaseUpdate.mSender = pSender; |
||
1127 | vDatabaseUpdate.mUserName = pUserName; |
||
1128 | vDatabaseUpdate.mDatabaseID = pDatabaseID; |
||
1129 | vDatabaseUpdate.mRevision = pRevision; |
||
1130 | vDatabaseUpdate.mSinceRevision = pSinceRevision; |
||
1131 | vDatabaseUpdate.mChanges = {}; |
||
1132 | vDatabaseUpdate.mLastMessageTime = Calendar_GetCurrentLocalDateTimeStamp(); |
||
1133 | |||
1134 | table.insert(gGroupCalendar_Queue.DatabaseUpdates, vDatabaseUpdate); |
||
1135 | end |
||
1136 | |||
1137 | function CalendarNetwork_InsertEventUpdate(pSender, pUserName, pDatabaseID, pRevision, pEventID, pCommand) |
||
1138 | local vDatabaseUpdate = CalendarNetwork_FindDatabaseUpdate(pSender, pUserName, pDatabaseID); |
||
1139 | |||
1140 | if not vDatabaseUpdate then |
||
1141 | return; |
||
1142 | end |
||
1143 | |||
1144 | -- Bump the update time |
||
1145 | |||
1146 | vDatabaseUpdate.mLastMessageTime = Calendar_GetCurrentLocalDateTimeStamp(); |
||
1147 | |||
1148 | -- |
||
1149 | |||
1150 | local vChanges = vDatabaseUpdate.mChanges[pRevision]; |
||
1151 | |||
1152 | if not vChanges then |
||
1153 | vChanges = {}; |
||
1154 | vDatabaseUpdate.mChanges[pRevision] = vChanges; |
||
1155 | end |
||
1156 | |||
1157 | -- Reconstruct the change string |
||
1158 | |||
1159 | local vChangeString = "EVT:"..pEventID; |
||
1160 | |||
1161 | for vIndex, vCommand in pCommand do |
||
1162 | vChangeString = vChangeString.."/"..vCommand.opcode; |
||
1163 | |||
1164 | if vCommand.operandString and vCommand.operandString ~= "" then |
||
1165 | vChangeString = vChangeString..":"..vCommand.operandString; |
||
1166 | end |
||
1167 | end |
||
1168 | |||
1169 | -- Save the string |
||
1170 | |||
1171 | table.insert(vChanges, vChangeString); |
||
1172 | end |
||
1173 | |||
1174 | function CalendarNetwork_EndDatabaseUpdate(pSender, pUserName, pDatabaseID, pRevision, pSinceRevision) |
||
1175 | local vDatabaseUpdate = CalendarNetwork_FindDatabaseUpdate(pSender, pUserName, pDatabaseID, true); |
||
1176 | |||
1177 | if not vDatabaseUpdate then |
||
1178 | return; |
||
1179 | end |
||
1180 | |||
1181 | -- Sanity check: make sure the sinceRevision field matches the original UPD message |
||
1182 | |||
1183 | if vDatabaseUpdate.mSinceRevision ~= pSinceRevision then |
||
1184 | return; |
||
1185 | end |
||
1186 | |||
1187 | -- The update was received successfully. |
||
1188 | -- Copy the changes to the change list |
||
1189 | |||
1190 | if gGroupCalendar_Settings.DebugUpdates then |
||
1191 | Calendar_DebugMessage("CalendarNetwork_EndDatabaseUpdate: Process update for "..pUserName..","..pDatabaseID..","..pRevision.." since revision "..pSinceRevision.." from "..pSender); |
||
1192 | end |
||
1193 | |||
1194 | local vDatabase = EventDatabase_GetDatabase(pUserName, true); |
||
1195 | local vDatabaseChanges = vDatabase.Changes; |
||
1196 | local vReconstructDatabase = false; |
||
1197 | |||
1198 | -- If the update is for one of our own databases process it |
||
1199 | -- separately |
||
1200 | |||
1201 | if vDatabase.IsPlayerOwned then |
||
1202 | CalendarNetwork_AskProcessSelfUpdate(vDatabaseUpdate); |
||
1203 | return; |
||
1204 | end |
||
1205 | |||
1206 | -- Process the update |
||
1207 | |||
1208 | CalendarNetwork_ProcessDatabaseUpdate(vDatabaseUpdate, false); |
||
1209 | end |
||
1210 | |||
1211 | function CalendarNetwork_ProcessDatabaseUpdate(pDatabaseUpdate, pForceReconstruct) |
||
1212 | local vIsOwnerUpdate = pDatabaseUpdate.mSender == pDatabaseUpdate.mUserName; |
||
1213 | local vDatabase = EventDatabase_GetDatabase(pDatabaseUpdate.mUserName, true); |
||
1214 | local vDatabaseChanges = vDatabase.Changes; |
||
1215 | local vReconstructDatabase = pForceReconstruct; |
||
1216 | |||
1217 | if not vDatabaseChanges |
||
1218 | or vDatabaseChanges.ID ~= pDatabaseUpdate.mDatabaseID then |
||
1219 | vDatabase.Changes = CalendarChanges_New(pDatabaseUpdate.mDatabaseID); |
||
1220 | vDatabaseChanges = vDatabase.Changes; |
||
1221 | end |
||
1222 | |||
1223 | for vRevision = pDatabaseUpdate.mSinceRevision + 1, pDatabaseUpdate.mRevision do |
||
1224 | local vChanges = pDatabaseUpdate.mChanges[vRevision]; |
||
1225 | |||
1226 | -- If the revision is newer than what we have, insert the new data |
||
1227 | |||
1228 | if vRevision > vDatabaseChanges.Revision then |
||
1229 | CalendarChanges_SetChangeList(vDatabaseChanges, vRevision, vChanges); |
||
1230 | |||
1231 | if vChanges then |
||
1232 | EventDatabase_ExecuteChangeList(vDatabase, vChanges, true); |
||
1233 | end |
||
1234 | |||
1235 | -- If the revision overlaps what we have and the update is from |
||
1236 | -- the owner, then compare the data to make sure it's intact. If |
||
1237 | -- it doesn't match then update the changes and flag the database |
||
1238 | -- for reconstruction |
||
1239 | |||
1240 | elseif vIsOwnerUpdate then |
||
1241 | -- If we're not reconstructing then compare the owner's changes to what |
||
1242 | -- we've gotten before and see if they match. Switch to reconstruction |
||
1243 | -- mode if there's a discrepancy |
||
1244 | |||
1245 | if not vReconstructDatabase then |
||
1246 | local vChangeList = CalendarChanges_GetChangeList(vDatabaseChanges, vRevision); |
||
1247 | |||
1248 | if ((vChanges ~= nil) ~= (vChangeList ~= nil)) |
||
1249 | or (vChangeList ~= nil and table.getn(vChangeList) ~= table.getn(vChanges)) then |
||
1250 | vReconstructDatabase = true; |
||
1251 | |||
1252 | if gGroupCalendar_Settings.DebugReconstruct then |
||
1253 | Calendar_DebugMessage("Reconstructing "..vDatabase.UserName.." because changes for revision "..vRevision.." are different lengths"); |
||
1254 | end |
||
1255 | elseif vChanges ~= nil then |
||
1256 | for vChangeIndex, vChange in vChanges do |
||
1257 | local vOldChange = vChangeList[vChangeIndex]; |
||
1258 | |||
1259 | if vOldChange ~= vChange then |
||
1260 | vReconstructDatabase = true; |
||
1261 | |||
1262 | if gGroupCalendar_Settings.DebugReconstruct then |
||
1263 | Calendar_DebugMessage("Reconstructing "..vDatabase.UserName.." because change "..vChangeIndex.." for revision "..vRevision.." doesn't match"); |
||
1264 | Calendar_DebugMessage("Previously: "..vOldChange); |
||
1265 | Calendar_DebugMessage("Now: "..vChange); |
||
1266 | end |
||
1267 | break; |
||
1268 | end |
||
1269 | end |
||
1270 | end |
||
1271 | end |
||
1272 | |||
1273 | -- Just copy the changes over if we're in re-construction mode |
||
1274 | |||
1275 | if vReconstructDatabase then |
||
1276 | CalendarChanges_SetChangeList(vDatabaseChanges, vRevision, vChanges); |
||
1277 | end |
||
1278 | end |
||
1279 | end |
||
1280 | |||
1281 | -- Make sure the current revision stamp matches the update |
||
1282 | |||
1283 | vDatabaseChanges.Revision = pDatabaseUpdate.mRevision; |
||
1284 | |||
1285 | -- Update AuthRevision if the update came from the owner |
||
1286 | |||
1287 | if vIsOwnerUpdate |
||
1288 | and pDatabaseUpdate.mSinceRevision <= vDatabaseChanges.AuthRevision then |
||
1289 | vDatabaseChanges.AuthRevision = pDatabaseUpdate.mRevision; |
||
1290 | end |
||
1291 | |||
1292 | if vReconstructDatabase then |
||
1293 | EventDatabase_ReconstructDatabase(vDatabase); |
||
1294 | else |
||
1295 | GroupCalendar_MajorDatabaseChange(vDatabase); |
||
1296 | end |
||
1297 | end |
||
1298 | |||
1299 | StaticPopupDialogs["CONFIRM_CALENDAR_SELF_UPDATE"] = { |
||
1300 | text = TEXT(GroupCalendar_cConfirmSelfUpdateMsg), |
||
1301 | button1 = TEXT(GroupCalendar_cUpdate), |
||
1302 | button2 = TEXT(CANCEL), |
||
1303 | OnAccept = function() CalendarNetwork_ProcessSelfUpdate(); end, |
||
1304 | OnCancel = function() CalendarNetwork_RejectSelfUpdate(); end, |
||
1305 | timeout = 0, |
||
1306 | whileDead = 1, |
||
1307 | hideOnEscape = 1, |
||
1308 | showAlert = 1, |
||
1309 | }; |
||
1310 | |||
1311 | gGroupCalendar_DidAskSelfUpdate = false; |
||
1312 | gGroupCalendar_SelfDatabaseUpdate = nil; |
||
1313 | |||
1314 | function CalendarNetwork_AskProcessSelfUpdate(pDatabaseUpdate) |
||
1315 | -- Only ask once |
||
1316 | |||
1317 | if gGroupCalendar_DidAskSelfUpdate then |
||
1318 | return; |
||
1319 | end |
||
1320 | |||
1321 | gGroupCalendar_DidAskSelfUpdate = true; |
||
1322 | |||
1323 | gGroupCalendar_SelfDatabaseUpdate = pDatabaseUpdate; |
||
1324 | |||
1325 | -- Format the message |
||
1326 | |||
1327 | local vMessage = Calendar_FormatNamed(GroupCalendar_cConfirmSelfUpdateParamFormat, pDatabaseUpdate); |
||
1328 | |||
1329 | -- Show the dialog |
||
1330 | |||
1331 | StaticPopup_Show("CONFIRM_CALENDAR_SELF_UPDATE", vMessage); |
||
1332 | end |
||
1333 | |||
1334 | StaticPopupDialogs["CONFIRM_CALENDAR_SELF_RSVP_UPDATE"] = { |
||
1335 | text = TEXT(GroupCalendar_cConfirmSelfUpdateMsg), |
||
1336 | button1 = TEXT(GroupCalendar_cUpdate), |
||
1337 | button2 = TEXT(CANCEL), |
||
1338 | OnAccept = function() CalendarNetwork_ProcessSelfRSVPUpdate(); end, |
||
1339 | OnCancel = function() CalendarNetwork_RejectSelfRSVPUpdate(); end, |
||
1340 | timeout = 0, |
||
1341 | whileDead = 1, |
||
1342 | hideOnEscape = 1, |
||
1343 | showAlert = 1, |
||
1344 | }; |
||
1345 | |||
1346 | gGroupCalendar_DidAskSelfRSVPUpdate = false; |
||
1347 | gGroupCalendar_SelfRSVPUpdate = nil; |
||
1348 | |||
1349 | function CalendarNetwork_AskProcessSelfRSVPUpdate(pRSVPUpdate) |
||
1350 | -- Only ask once |
||
1351 | |||
1352 | if gGroupCalendar_DidAskSelfRSVPUpdate then |
||
1353 | return; |
||
1354 | end |
||
1355 | |||
1356 | gGroupCalendar_DidAskSelfRSVPUpdate = true; |
||
1357 | gGroupCalendar_SelfRSVPUpdate = pRSVPUpdate; |
||
1358 | |||
1359 | -- Format the message |
||
1360 | |||
1361 | local vMessage = Calendar_FormatNamed(GroupCalendar_cConfirmSelfRSVPUpdateParamFormat, pRSVPUpdate); |
||
1362 | |||
1363 | -- Show the dialog |
||
1364 | |||
1365 | StaticPopup_Show("CONFIRM_CALENDAR_SELF_RSVP_UPDATE", vMessage); |
||
1366 | end |
||
1367 | |||
1368 | function CalendarNetwork_ProcessSelfUpdate() |
||
1369 | CalendarNetwork_ProcessDatabaseUpdate(gGroupCalendar_SelfDatabaseUpdate, true); |
||
1370 | end |
||
1371 | |||
1372 | function CalendarNetwork_RejectSelfUpdate() |
||
1373 | local vDatabase = EventDatabase_GetDatabase(gGroupCalendar_SelfDatabaseUpdate.mUserName, true); |
||
1374 | |||
1375 | if not vDatabase then |
||
1376 | return; |
||
1377 | end |
||
1378 | |||
1379 | EventDatabase_RebuildDatabase(vDatabase); |
||
1380 | end |
||
1381 | |||
1382 | function CalendarNetwork_CancelDatabaseUpdate(pSender, pUserName, pDatabaseID) |
||
1383 | CalendarNetwork_FindDatabaseUpdate(pSender, pUserName, pDatabaseID, true); |
||
1384 | end |
||
1385 | |||
1386 | function CalendarNetwork_FindOpenEventChangeRecord(pChanges, pEventID) |
||
1387 | for vIndex, vChange in pChanges do |
||
1388 | if vChange.mEventID == pEventID |
||
1389 | and vChange.mOpen then |
||
1390 | return vChange; |
||
1391 | end |
||
1392 | end |
||
1393 | |||
1394 | return nil; |
||
1395 | end |
||
1396 | |||
1397 | function CalendarNetwork_KillSendersDatabaseUpdates(pSender) |
||
1398 | local vDatabaseUpdate = CalendarNetwork_FindDatabaseUpdate(pSender, nil, nil, true); |
||
1399 | |||
1400 | if not vDatabaseUpdate |
||
1401 | or vDatabaseUpdate.mUserName == pDontRequestForUserName then |
||
1402 | return; |
||
1403 | end |
||
1404 | |||
1405 | CalendarNetwork_RequestUpdateForUser(vDatabaseUpdate.mUserName, "DB"); |
||
1406 | end |
||
1407 | |||
1408 | function CalendarNetwork_FindDatabaseUpdate(pSender, pUserName, pDatabaseID, pDelete) |
||
1409 | for vIndex, vDatabaseUpdate in gGroupCalendar_Queue.DatabaseUpdates do |
||
1410 | if (pSender == nil or vDatabaseUpdate.mSender == pSender) |
||
1411 | and (pUserName == nil or vDatabaseUpdate.mUserName == pUserName) |
||
1412 | and (pDatabaseID == nil or vDatabaseUpdate.mDatabaseID == pDatabaseID) then |
||
1413 | -- Delete the update if requested |
||
1414 | |||
1415 | if pDelete then |
||
1416 | table.remove(gGroupCalendar_Queue.DatabaseUpdates, vIndex); |
||
1417 | end |
||
1418 | |||
1419 | return vDatabaseUpdate; |
||
1420 | end |
||
1421 | end |
||
1422 | |||
1423 | return nil; |
||
1424 | end |
||
1425 | |||
1426 | function CalendarNetwork_DeleteRSVPs(pSender, pUserName, pDatabaseID, pRevision) |
||
1427 | -- Get the database |
||
1428 | |||
1429 | local vDatabase = EventDatabase_GetDatabase(pUserName, false); |
||
1430 | |||
1431 | -- Nothing to do if we don't even have the database |
||
1432 | |||
1433 | if not vDatabase then |
||
1434 | return; |
||
1435 | end |
||
1436 | |||
1437 | -- Bail out if our stuff is better |
||
1438 | |||
1439 | if not CalendarNetwork_UpdateIsBetterThanOurs(pSender, pUserName, pDatabaseID, pRevision, vDatabase, vDatabase.RSVPs) then |
||
1440 | return; |
||
1441 | end |
||
1442 | |||
1443 | -- Empty the specified changelist |
||
1444 | |||
1445 | EventDatabase_PurgeRSVPs(vDatabase, pDatabaseID); |
||
1446 | vDatabase.RSVPs.Revision = pRevision; |
||
1447 | end |
||
1448 | |||
1449 | function CalendarNetwork_BeginRSVPUpdate(pSender, pUserName, pDatabaseID, pRevision, pSinceRevision) |
||
1450 | -- If the same sender has a pending update already in progress, kill it |
||
1451 | |||
1452 | CalendarNetwork_KillSendersRSVPUpdates(pSender, pUserName); |
||
1453 | |||
1454 | -- Get the database |
||
1455 | |||
1456 | local vDatabase = EventDatabase_GetDatabase(pUserName, false); |
||
1457 | |||
1458 | -- Don't listen to updates for our own databases |
||
1459 | |||
1460 | if vDatabase |
||
1461 | and vDatabase.IsPlayerOwned |
||
1462 | and not gGroupCalendar_Settings.AllowSelfUpdate then |
||
1463 | return; |
||
1464 | end |
||
1465 | |||
1466 | local vChanges; |
||
1467 | |||
1468 | if vDatabase then |
||
1469 | vChanges = vDatabase.RSVPs; |
||
1470 | else |
||
1471 | vChanges = nil; |
||
1472 | end |
||
1473 | |||
1474 | -- Ignore the update if it isn't from the owner and |
||
1475 | -- our ID is newer |
||
1476 | |||
1477 | if string.lower(pSender) ~= string.lower(pUserName) |
||
1478 | and vChanges then |
||
1479 | if (vChanges.ID > pDatabaseID) |
||
1480 | or (vChanges.ID == pDatabaseID |
||
1481 | and vChanges.Revision >= pRevision) then |
||
1482 | return; |
||
1483 | end |
||
1484 | end |
||
1485 | |||
1486 | -- If it's from the owner and isn't the same revision as ours, |
||
1487 | -- then delete the database. If the update is from revision |
||
1488 | -- zero go ahead with the update otherwise ignore it and request |
||
1489 | -- and update from zero |
||
1490 | |||
1491 | if string.lower(pSender) == string.lower(pUserName) |
||
1492 | and vChanges |
||
1493 | and vChanges.ID ~= pDatabaseID then |
||
1494 | EventDatabase_PurgeRSVPs(vDatabase, pDatabaseID); |
||
1495 | |||
1496 | if pSinceRevision ~= 0 then |
||
1497 | -- Request an update and exit |
||
1498 | |||
1499 | CalendarNetwork_QueueRFURequest(pUserName, "RAT", pDatabaseID, 0) |
||
1500 | return; |
||
1501 | end |
||
1502 | end |
||
1503 | |||
1504 | -- See if there's another update for the same database already in progress |
||
1505 | |||
1506 | local vRSVPUpdate = CalendarNetwork_FindRSVPUpdate(nil, pUserName, nil); |
||
1507 | |||
1508 | if vRSVPUpdate then |
||
1509 | -- If the new update is from the owner or |
||
1510 | -- the old one isn't from the owner and is a higher revision, |
||
1511 | -- then cancel the old update |
||
1512 | |||
1513 | if string.lower(pSender) == string.lower(pUserName) |
||
1514 | or (vRSVPUpdate.mSender ~= vRSVPUpdate.mUserName |
||
1515 | and CalendarNetwork_DatabaseIsNewer(vRSVPUpdate.mDatabaseID, vRSVPUpdate.mRevision, pDatabaseID, pRevision)) then |
||
1516 | CalendarNetwork_CancelRSVPUpdate(nil, pUserName, nil); |
||
1517 | |||
1518 | -- Otherwise cancel this one |
||
1519 | |||
1520 | else |
||
1521 | return; |
||
1522 | end |
||
1523 | end |
||
1524 | |||
1525 | if gGroupCalendar_Settings.DebugUpdates then |
||
1526 | Calendar_DebugMessage("CalendarNetwork_BeginRSVPUpdate: "..pUserName..","..pRevision.." since revision "..pSinceRevision.." from "..pSender); |
||
1527 | end |
||
1528 | |||
1529 | -- Can't accept updates which don't cover the last revision we received |
||
1530 | |||
1531 | if vChanges |
||
1532 | and pSinceRevision > vChanges.Revision then |
||
1533 | -- Ask for another copy of the update starting with the revision we need |
||
1534 | |||
1535 | CalendarNetwork_QueueRFURequest(pUserName, "RAT", pDatabaseID, vChanges.Revision); |
||
1536 | return; |
||
1537 | end |
||
1538 | |||
1539 | -- Create the update record |
||
1540 | |||
1541 | vRSVPUpdate = {}; |
||
1542 | |||
1543 | vRSVPUpdate.mSender = pSender; |
||
1544 | vRSVPUpdate.mUserName = pUserName; |
||
1545 | vRSVPUpdate.mDatabaseID = pDatabaseID; |
||
1546 | vRSVPUpdate.mRevision = pRevision; |
||
1547 | vRSVPUpdate.mSinceRevision = pSinceRevision; |
||
1548 | vRSVPUpdate.mChanges = {}; |
||
1549 | vRSVPUpdate.mLastMessageTime = Calendar_GetCurrentLocalDateTimeStamp(); |
||
1550 | |||
1551 | table.insert(gGroupCalendar_Queue.RSVPUpdates, vRSVPUpdate); |
||
1552 | end |
||
1553 | |||
1554 | function CalendarNetwork_InsertRSVPUpdate(pSender, pUserName, pDatabaseID, pRevision, pEventFields) |
||
1555 | local vRSVPUpdate = CalendarNetwork_FindRSVPUpdate(pSender, pUserName, pDatabaseID); |
||
1556 | |||
1557 | if not vRSVPUpdate then |
||
1558 | if gGroupCalendar_Settings.DebugUpdates then |
||
1559 | Calendar_DebugMessage("CalendarNetwork_InsertRSVPUpdate: Ignoring update for "..pUserName..","..pDatabaseID..": Update not found"); |
||
1560 | end |
||
1561 | return; |
||
1562 | end |
||
1563 | |||
1564 | -- Bump the update time |
||
1565 | |||
1566 | vRSVPUpdate.mLastMessageTime = Calendar_GetCurrentLocalDateTimeStamp(); |
||
1567 | |||
1568 | -- |
||
1569 | |||
1570 | local vChanges = vRSVPUpdate.mChanges[pRevision]; |
||
1571 | |||
1572 | if not vChanges then |
||
1573 | vChanges = {}; |
||
1574 | vRSVPUpdate.mChanges[pRevision] = vChanges; |
||
1575 | end |
||
1576 | |||
1577 | -- Process the event command |
||
1578 | |||
1579 | local vChangeString = "EVT:"..pEventFields; |
||
1580 | |||
1581 | table.insert(vChanges, vChangeString); |
||
1582 | end |
||
1583 | |||
1584 | function CalendarNetwork_EndRSVPUpdate(pSender, pUserName, pDatabaseID, pRevision, pSinceRevision) |
||
1585 | local vRSVPUpdate = CalendarNetwork_FindRSVPUpdate(pSender, pUserName, pDatabaseID, true); |
||
1586 | |||
1587 | if not vRSVPUpdate then |
||
1588 | return; |
||
1589 | end |
||
1590 | |||
1591 | -- Sanity check: make sure the sinceRevision field matches the original UPD message |
||
1592 | |||
1593 | if vRSVPUpdate.mSinceRevision ~= pSinceRevision then |
||
1594 | return; |
||
1595 | end |
||
1596 | |||
1597 | -- The update was received successfully. |
||
1598 | -- Process the commands in the update |
||
1599 | |||
1600 | if gGroupCalendar_Settings.DebugUpdates then |
||
1601 | Calendar_DebugMessage("CalendarNetwork_EndRSVPUpdate: Process update for "..pUserName..","..pRevision.." since revision "..pSinceRevision.." from "..pSender); |
||
1602 | end |
||
1603 | |||
1604 | local vDatabase = EventDatabase_GetDatabase(pUserName, true); |
||
1605 | local vRSVPChanges = vDatabase.RSVPs; |
||
1606 | local vReconstructRSVPs = false; |
||
1607 | |||
1608 | -- If the update is for one of our own databases process it |
||
1609 | -- separately |
||
1610 | |||
1611 | if vDatabase.IsPlayerOwned then |
||
1612 | CalendarNetwork_AskProcessSelfRSVPUpdate(vRSVPUpdate); |
||
1613 | return; |
||
1614 | end |
||
1615 | |||
1616 | -- Process the update |
||
1617 | |||
1618 | CalendarNetwork_ProcessRSVPUpdate(vRSVPUpdate, false); |
||
1619 | end |
||
1620 | |||
1621 | function CalendarNetwork_ProcessRSVPUpdate(pRSVPUpdate, pForceReconstruct) |
||
1622 | local vIsOwnerUpdate = pRSVPUpdate.mSender == pRSVPUpdate.mUserName; |
||
1623 | local vDatabase = EventDatabase_GetDatabase(pRSVPUpdate.mUserName, true); |
||
1624 | local vRSVPChanges = vDatabase.RSVPs; |
||
1625 | |||
1626 | if not vRSVPChanges |
||
1627 | or vRSVPChanges.ID ~= pRSVPUpdate.mDatabaseID then |
||
1628 | vDatabase.RSVPs = CalendarChanges_New(pRSVPUpdate.mDatabaseID); |
||
1629 | vRSVPChanges = vDatabase.RSVPs; |
||
1630 | end |
||
1631 | |||
1632 | for vRevision = pRSVPUpdate.mSinceRevision + 1, pRSVPUpdate.mRevision do |
||
1633 | local vChanges = pRSVPUpdate.mChanges[vRevision]; |
||
1634 | |||
1635 | -- If the revision is newer than what we have, insert the new data |
||
1636 | |||
1637 | if vRevision > vRSVPChanges.Revision then |
||
1638 | CalendarChanges_SetChangeList(vRSVPChanges, vRevision, vChanges); |
||
1639 | CalendarChanges_Close(vRSVPChanges, vRevision); |
||
1640 | |||
1641 | if vChanges then |
||
1642 | EventDatabase_ExecuteRSVPChangeList(vDatabase, vChanges, true); |
||
1643 | end |
||
1644 | elseif vIsOwnerUpdate and vRevision > vRSVPChanges.AuthRevision then |
||
1645 | if gGroupCalendar_Settings.DebugUpdates then |
||
1646 | Calendar_DebugMessage("CalendarNetwork_EndRSVPUpdate: Ignoring owner update for "..vRevision..": Not implemented"); |
||
1647 | end |
||
1648 | else |
||
1649 | if gGroupCalendar_Settings.DebugUpdates then |
||
1650 | Calendar_DebugMessage("CalendarNetwork_EndRSVPUpdate: Ignoring revision "..vRevision..": Already exists"); |
||
1651 | end |
||
1652 | end |
||
1653 | end |
||
1654 | |||
1655 | vRSVPChanges.Revision = pRSVPUpdate.mRevision; |
||
1656 | |||
1657 | -- Update AuthRevision if the update came from the owner |
||
1658 | |||
1659 | if vIsOwnerUpdate |
||
1660 | and pRSVPUpdate.mSinceRevision <= vRSVPChanges.AuthRevision then |
||
1661 | vRSVPChanges.AuthRevision = pRSVPUpdate.mRevision; |
||
1662 | end |
||
1663 | end |
||
1664 | |||
1665 | function CalendarNetwork_ProcessSelfRSVPUpdate() |
||
1666 | CalendarNetwork_ProcessRSVPUpdate(gGroupCalendar_SelfRSVPUpdate, true); |
||
1667 | end |
||
1668 | |||
1669 | function CalendarNetwork_RejectSelfRSVPUpdate() |
||
1670 | local vDatabase = EventDatabase_GetDatabase(gGroupCalendar_SelfRSVPUpdate.mUserName, true); |
||
1671 | |||
1672 | if not vDatabase then |
||
1673 | return; |
||
1674 | end |
||
1675 | |||
1676 | EventDatabase_RebuildRSVPs(vDatabase); |
||
1677 | end |
||
1678 | |||
1679 | function CalendarNetwork_CancelRSVPUpdate(pSender, pUserName, pDatabaseID) |
||
1680 | CalendarNetwork_FindRSVPUpdate(pSender, pUserName, pDatabaseID, true); |
||
1681 | end |
||
1682 | |||
1683 | function CalendarNetwork_KillSendersRSVPUpdates(pSender, pDontRequestForUserName) |
||
1684 | local vRSVPUpdate = CalendarNetwork_FindRSVPUpdate(pSender, nil, nil, pDelete); |
||
1685 | |||
1686 | if not vRSVPUpdate |
||
1687 | or vRSVPUpdate.mUserName == pDontRequestForUserName then |
||
1688 | return; |
||
1689 | end |
||
1690 | |||
1691 | CalendarNetwork_RequestUpdateForUser(vRSVPUpdate.mUserName, "RAT"); |
||
1692 | end |
||
1693 | |||
1694 | function CalendarNetwork_FindRSVPUpdate(pSender, pUserName, pDatabaseID, pDelete) |
||
1695 | for vIndex, vRSVPUpdate in gGroupCalendar_Queue.RSVPUpdates do |
||
1696 | if (pSender == nil or vRSVPUpdate.mSender == pSender) |
||
1697 | and (pUserName == nil or vRSVPUpdate.mUserName == pUserName) |
||
1698 | and (pDatabaseID == nil or vRSVPUpdate.mDatabaseID == pDatabaseID) then |
||
1699 | -- Delete the update if requested |
||
1700 | |||
1701 | if pDelete then |
||
1702 | table.remove(gGroupCalendar_Queue.RSVPUpdates,vIndex); |
||
1703 | end |
||
1704 | |||
1705 | return vRSVPUpdate; |
||
1706 | end |
||
1707 | end |
||
1708 | |||
1709 | return nil; |
||
1710 | end |
||
1711 | |||
1712 | function CalendarNetwork_KillOldUpdates(pDatabaseTag, pUpdates, pMinimumTime) |
||
1713 | local vIndex = 1; |
||
1714 | local vNumUpdates = table.getn(pUpdates); |
||
1715 | |||
1716 | while vIndex <= vNumUpdates do |
||
1717 | local vUpdate = pUpdates[vIndex]; |
||
1718 | |||
1719 | if vUpdate.mLastMessageTime < pMinimumTime then |
||
1720 | table.remove(pUpdates, vIndex); |
||
1721 | vNumUpdates = vNumUpdates - 1; |
||
1722 | |||
1723 | -- Re-request the update |
||
1724 | |||
1725 | CalendarNetwork_RequestUpdateForUser(vUpdate.mUserName, pDatabaseTag, false); |
||
1726 | else |
||
1727 | vIndex = vIndex + 1; |
||
1728 | end |
||
1729 | end |
||
1730 | end |
||
1731 | |||
1732 | function CalendarNetwork_ParseCommandString(pCommandString) |
||
1733 | |||
1734 | -- Verify the command begins with the message prefix |
||
1735 | |||
1736 | if strsub(pCommandString, 1, gGroupCalendar_MessagePrefixLength) ~= gGroupCalendar_MessagePrefix then |
||
1737 | return nil; |
||
1738 | end |
||
1739 | |||
1740 | local vCommandString = strsub(pCommandString, gGroupCalendar_MessagePrefixLength); |
||
1741 | |||
1742 | return CalendarNetwork_ParseCommandSubString(vCommandString) |
||
1743 | end |
||
1744 | |||
1745 | function CalendarNetwork_ParseCommandSubString(pCommandString) |
||
1746 | -- Break the command into parts |
||
1747 | |||
1748 | local vCommand = {}; |
||
1749 | |||
1750 | for vOpcode, vOperands in string.gfind(pCommandString, "/(%w+):*([^/]*)") do |
||
1751 | local vOperation = {}; |
||
1752 | |||
1753 | vOperation.opcode = vOpcode; |
||
1754 | vOperation.operandString = vOperands; |
||
1755 | vOperation.operands = CalendarNetwork_ParseParameterString(vOperands); |
||
1756 | |||
1757 | table.insert(vCommand, vOperation); |
||
1758 | end |
||
1759 | |||
1760 | return vCommand; |
||
1761 | end |
||
1762 | |||
1763 | function CalendarNetwork_ParseParameterString(pParameterString) |
||
1764 | local vParameters = {}; |
||
1765 | local vIndex = 0; |
||
1766 | local vFound = true; |
||
1767 | local vStartIndex = 1; |
||
1768 | |||
1769 | while vFound do |
||
1770 | local vEndIndex; |
||
1771 | |||
1772 | vFound, vEndIndex, vParameter = string.find(pParameterString, "([^,]*),", vStartIndex); |
||
1773 | |||
1774 | vIndex = vIndex + 1; |
||
1775 | |||
1776 | if not vFound then |
||
1777 | vParameters[vIndex] = string.sub(pParameterString, vStartIndex); |
||
1778 | break; |
||
1779 | end |
||
1780 | |||
1781 | vParameters[vIndex] = vParameter; |
||
1782 | vStartIndex = vEndIndex + 1; |
||
1783 | end |
||
1784 | |||
1785 | return vParameters; |
||
1786 | end |
||
1787 | |||
1788 | function CalendarNetwork_NewEvent(pDatabase, pEvent) |
||
1789 | -- Don't record private events in the change history |
||
1790 | |||
1791 | if pEvent.mPrivate then |
||
1792 | return; |
||
1793 | end |
||
1794 | |||
1795 | -- Append a change record for the event |
||
1796 | |||
1797 | local vChangeList = EventDatabase_GetCurrentChangeList(pDatabase); |
||
1798 | |||
1799 | EventDatabase_AppendNewEvent(vChangeList, pEvent, EventDatabase_GetEventPath(pEvent)); |
||
1800 | end |
||
1801 | |||
1802 | function CalendarNetwork_EventChanged(pDatabase, pEvent, pChangedFields) |
||
1803 | -- Don't record private events in the change history |
||
1804 | |||
1805 | if pEvent.mPrivate then |
||
1806 | return; |
||
1807 | end |
||
1808 | |||
1809 | -- Append a change record for the event |
||
1810 | |||
1811 | local vChangeList = EventDatabase_GetCurrentChangeList(pDatabase); |
||
1812 | |||
1813 | EventDatabase_AppendEventUpdate( |
||
1814 | vChangeList, |
||
1815 | pEvent, |
||
1816 | EventDatabase_GetEventPath(pEvent), |
||
1817 | pChangedFields); |
||
1818 | end |
||
1819 | |||
1820 | function CalendarNetwork_RemovingEvent(pDatabase, pEvent) |
||
1821 | -- Don't record private events in the change history |
||
1822 | |||
1823 | if pEvent.mPrivate then |
||
1824 | return; |
||
1825 | end |
||
1826 | |||
1827 | -- Remove any references to the event from the change history |
||
1828 | |||
1829 | EventDatabase_RemoveEventChanges(pDatabase, pEvent); |
||
1830 | |||
1831 | -- Insert a delete event |
||
1832 | |||
1833 | local vChangeList = EventDatabase_GetCurrentChangeList(pDatabase); |
||
1834 | |||
1835 | table.insert(vChangeList, EventDatabase_GetEventPath(pEvent).."DEL"); |
||
1836 | end |
||
1837 | |||
1838 | function CalendarNetwork_SendRevisionChanged(pChanges, pLabel, pUserName) |
||
1839 | -- Just leave if there's no channel to communicate on |
||
1840 | -- or no changes to announce |
||
1841 | |||
1842 | if not gGroupCalendar_Channel.ID |
||
1843 | or not pChanges then |
||
1844 | return; |
||
1845 | end |
||
1846 | |||
1847 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix..CalendarChanges_GetRevisionPath(pLabel, pUserName, pChanges.ID, pChanges.Revision).."NOU"); |
||
1848 | end |
||
1849 | |||
1850 | function CalendarNetwork_DBRevisionChanged(pDatabase) |
||
1851 | CalendarNetwork_SendRevisionChanged(pDatabase.Changes, "DB", pDatabase.UserName); |
||
1852 | end |
||
1853 | |||
1854 | function CalendarNetwork_RSVPRevisionChanged(pDatabase) |
||
1855 | CalendarNetwork_SendRevisionChanged(pDatabase.RSVPs, "RAT", pDatabase.UserName); |
||
1856 | end |
||
1857 | |||
1858 | function CalendarNetwork_RequestAllUpdate() |
||
1859 | -- Just leave if there's no channel to communicate on |
||
1860 | |||
1861 | if not gGroupCalendar_Channel.ID then |
||
1862 | return; |
||
1863 | end |
||
1864 | |||
1865 | -- Send the request immmediately since delaying it for channel silence will only |
||
1866 | -- increase the number of times that everyone has to transmit their NOU responses |
||
1867 | |||
1868 | CalendarNetwork_SendMessage(gGroupCalendar_MessagePrefix.."ALL/RFU"); |
||
1869 | end |
||
1870 | |||
1871 | function CalendarNetwork_RequestGuildUpdate(pGuildName, pMinRank) |
||
1872 | -- Just leave if there's no channel to communicate on |
||
1873 | |||
1874 | if not gGroupCalendar_Channel.ID then |
||
1875 | return; |
||
1876 | end |
||
1877 | |||
1878 | -- Send the request immmediately since delaying it for channel silence will only |
||
1879 | -- increase the number of times that everyone has to transmit their NOU responses |
||
1880 | |||
1881 | if pMinRank then |
||
1882 | CalendarNetwork_SendMessage(gGroupCalendar_MessagePrefix.."GLD:"..pGuildName..","..pMinRank.."/RFU"); |
||
1883 | else |
||
1884 | CalendarNetwork_SendMessage(gGroupCalendar_MessagePrefix.."GLD:"..pGuildName.."/RFU"); |
||
1885 | end |
||
1886 | end |
||
1887 | |||
1888 | function CalendarNetwork_RequestUpdateForUser(pUserName, pDatabaseTag, pRequestImmediately) |
||
1889 | local vDatabase = EventDatabase_GetDatabase(pUserName); |
||
1890 | |||
1891 | if not vDatabase then |
||
1892 | return; |
||
1893 | end |
||
1894 | |||
1895 | local vChanges; |
||
1896 | |||
1897 | if pDatabaseTag == "DB" then |
||
1898 | vChanges = vDatabase.Changes; |
||
1899 | elseif pDatabaseTag == "RAT" then |
||
1900 | vChanges = vDatabase.RSVPs; |
||
1901 | else |
||
1902 | Calendar_ErrorMessage("CalendarNetwork_RequestUpdateForUser: Unknown database tag "..pDatabaseTag); |
||
1903 | return; |
||
1904 | end |
||
1905 | |||
1906 | if not vChanges then |
||
1907 | return; |
||
1908 | end |
||
1909 | |||
1910 | CalendarNetwork_RequestUpdate(vDatabase, vChanges, pDatabaseTag, pRequestImmediately); |
||
1911 | end |
||
1912 | |||
1913 | function CalendarNetwork_RequestUpdate(pDatabase, pChanges, pDatabaseTag, pRequestImmediately) |
||
1914 | -- Just leave if there's no channel to communicate on |
||
1915 | |||
1916 | if not gGroupCalendar_Channel.ID then |
||
1917 | return; |
||
1918 | end |
||
1919 | |||
1920 | local vID, vRevision; |
||
1921 | |||
1922 | if pChanges then |
||
1923 | vID = pChanges.ID; |
||
1924 | vRevision = pChanges.Revision; |
||
1925 | else |
||
1926 | vID = 0; |
||
1927 | vRevision = 0; |
||
1928 | end |
||
1929 | |||
1930 | if pRequestImmediately then |
||
1931 | CalendarNetwork_SendMessage(gGroupCalendar_MessagePrefix..CalendarChanges_GetRevisionPath(pDatabaseTag, pDatabase.UserName, vID, vRevision, 0).."RFU"); |
||
1932 | else |
||
1933 | CalendarNetwork_QueueRFURequest(pDatabase.UserName, pDatabaseTag, vID, vRevision); |
||
1934 | end |
||
1935 | end |
||
1936 | |||
1937 | function CalendarNetwork_SendEmptyChanges(pChanges, pLabel, pUserName) |
||
1938 | local vID, vRevision; |
||
1939 | |||
1940 | if pChanges then |
||
1941 | vID = pChanges.ID; |
||
1942 | vRevision = pChanges.Revision; |
||
1943 | else |
||
1944 | vID = Calendar_GetCurrentDateTimeUT60(); |
||
1945 | vRevision = 0; |
||
1946 | end |
||
1947 | |||
1948 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix..CalendarChanges_GetRevisionPath(pLabel, pUserName, vID, vRevision).."DEL"); |
||
1949 | end |
||
1950 | |||
1951 | function CalendarNetwork_SendChanges(pChanges, pLabel, pUserName, pLockdown, pSinceRevision) |
||
1952 | if pLockdown then |
||
1953 | CalendarChanges_LockdownCurrentChangeList(pChanges); |
||
1954 | end |
||
1955 | |||
1956 | if CalendarChanges_IsEmpty(pChanges) then |
||
1957 | CalendarNetwork_SendEmptyChanges(pChanges, pLabel, pUserName); |
||
1958 | return; |
||
1959 | end |
||
1960 | |||
1961 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix..CalendarChanges_GetRevisionPath(pLabel, pUserName, pChanges.ID, pChanges.Revision).."UPD:"..pSinceRevision); |
||
1962 | |||
1963 | for vRevision = pSinceRevision + 1, pChanges.Revision do |
||
1964 | local vRevisionPath = CalendarChanges_GetRevisionPath(pLabel, pUserName, pChanges.ID, vRevision); |
||
1965 | local vChangeList = pChanges.ChangeList[vRevision]; |
||
1966 | |||
1967 | if vChangeList then |
||
1968 | vChangeList.IsOpen = nil; -- Make sure IsOpen is cleared, a bug may have caused it to remain open |
||
1969 | |||
1970 | for vIndex, vChange in vChangeList do |
||
1971 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix..vRevisionPath..vChange); |
||
1972 | end |
||
1973 | end |
||
1974 | end |
||
1975 | |||
1976 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix..CalendarChanges_GetRevisionPath(pLabel, pUserName, pChanges.ID, pChanges.Revision).."END:"..pSinceRevision); |
||
1977 | end |
||
1978 | |||
1979 | function CalendarNetwork_QueueOutboundMessage(pMessage) |
||
1980 | table.insert(gGroupCalendar_Queue.OutboundMessages, pMessage); |
||
1981 | |||
1982 | GroupCalendar_StartUpdateTimer(); |
||
1983 | end |
||
1984 | |||
1985 | function CalendarNetwork_QueueInboundMessage(pSender, pTrustLevel, pMessage) |
||
1986 | table.insert(gGroupCalendar_Queue.InboundMessages, {mSender = pSender, mTrustLevel = pTrustLevel, mMessage = pMessage}); |
||
1987 | |||
1988 | if table.getn(gGroupCalendar_Queue.InboundMessages) == 1 then |
||
1989 | gGroupCalendar_Queue.InboundDelay = 0; |
||
1990 | end |
||
1991 | |||
1992 | GroupCalendar_StartUpdateTimer(); |
||
1993 | end |
||
1994 | |||
1995 | function CalendarNetwork_QueueTask(pTaskFunc, pTaskParam, pDelay, pTaskID) |
||
1996 | local vTask = {mTaskFunc = pTaskFunc, mTaskParam = pTaskParam, mDelay = pDelay, mID = pTaskID}; |
||
1997 | |||
1998 | -- Ignore tasks with duplicate IDs |
||
1999 | |||
2000 | if pTaskID then |
||
2001 | for vIndex, vTask in gGroupCalendar_Queue.Tasks do |
||
2002 | if vTask.mID == pTaskID then |
||
2003 | return; |
||
2004 | end |
||
2005 | end |
||
2006 | end |
||
2007 | |||
2008 | -- Insert the task |
||
2009 | |||
2010 | table.insert(gGroupCalendar_Queue.Tasks, vTask); |
||
2011 | |||
2012 | CalendarNetwork_UpdateTaskQueueDelay(); |
||
2013 | |||
2014 | return true; |
||
2015 | end |
||
2016 | |||
2017 | function CalendarNetwork_UpdateTaskQueueDelay() |
||
2018 | local vDelay = nil; |
||
2019 | |||
2020 | for vIndex, vTask in gGroupCalendar_Queue.Tasks do |
||
2021 | if not vDelay |
||
2022 | or vTask.mDelay < vDelay then |
||
2023 | vDelay = vTask.mDelay; |
||
2024 | end |
||
2025 | end |
||
2026 | |||
2027 | gGroupCalendar_Queue.TasksDelay = vDelay; |
||
2028 | |||
2029 | if vDelay then |
||
2030 | GroupCalendar_StartUpdateTimer(); |
||
2031 | end |
||
2032 | end |
||
2033 | |||
2034 | function CalendarNetwork_SetTaskDelay(pTaskID, pDelay) |
||
2035 | -- Ignore tasks with duplicate IDs |
||
2036 | |||
2037 | for vIndex, vTask in gGroupCalendar_Queue.Tasks do |
||
2038 | if vTask.mID == pTaskID then |
||
2039 | vTask.mDelay = pDelay; |
||
2040 | CalendarNetwork_UpdateTaskQueueDelay(); |
||
2041 | return; |
||
2042 | end |
||
2043 | end |
||
2044 | end |
||
2045 | |||
2046 | function CalendarNetwork_QueueRequest(pRequest, pDelay, pPriority) |
||
2047 | pRequest.mDelay = pDelay; |
||
2048 | |||
2049 | if gGroupCalendar_Settings.DebugQueues then |
||
2050 | Calendar_DebugMessage("CalendarNetwork_QueueRequest: "..pRequest.mOpcode.." in "..pDelay.." seconds"); |
||
2051 | end |
||
2052 | |||
2053 | if not pPriority then |
||
2054 | pPriority = 2; |
||
2055 | end |
||
2056 | |||
2057 | table.insert(gGroupCalendar_Queue.Requests[pPriority], pRequest); |
||
2058 | |||
2059 | local vTotalRequests = 0; |
||
2060 | |||
2061 | for vPriority, vRequestQueue in gGroupCalendar_Queue.Requests do |
||
2062 | vTotalRequests = vTotalRequests + table.getn(gGroupCalendar_Queue.Requests[vPriority]); |
||
2063 | end |
||
2064 | |||
2065 | if vTotalRequests == 1 |
||
2066 | or (pRequest.mDelay < gGroupCalendar_Queue.RequestsDelay |
||
2067 | and pRequest.mDelay < gCalendarNetwork_RequestDelay.RequestQueue) then |
||
2068 | gGroupCalendar_Queue.RequestsDelay = pRequest.mDelay; |
||
2069 | end |
||
2070 | |||
2071 | GroupCalendar_StartUpdateTimer(); |
||
2072 | |||
2073 | return true; |
||
2074 | end |
||
2075 | |||
2076 | function CalendarNetwork_SetRequestPriority(pRequest, pPriority) |
||
2077 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2078 | for vIndex, vRequest in vRequests do |
||
2079 | if vRequest == pRequest then |
||
2080 | if vPriority ~= pPriority then |
||
2081 | table.remove(vRequests, vIndex); |
||
2082 | table.insert(gGroupCalendar_Queue.Requests[pPriority], vRequest); |
||
2083 | end |
||
2084 | return; |
||
2085 | end |
||
2086 | end |
||
2087 | end |
||
2088 | end |
||
2089 | |||
2090 | function CalendarNetwork_QueueUniqueOpcodeRequest(pRequest, pDelay) |
||
2091 | -- Remove an existing request with the same opcode |
||
2092 | |||
2093 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2094 | for vIndex, vRequest in vRequests do |
||
2095 | if vRequest.mOpcode == pRequest.mOpcode then |
||
2096 | table.remove(vRequests, vIndex); |
||
2097 | break; |
||
2098 | end |
||
2099 | end |
||
2100 | end |
||
2101 | |||
2102 | return CalendarNetwork_QueueRequest(pRequest, pDelay); |
||
2103 | end |
||
2104 | |||
2105 | function CalendarNetwork_QueueUniqueUserRequest(pRequest, pDelay) |
||
2106 | -- Remove an existing request with the same opcode and user name |
||
2107 | |||
2108 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2109 | for vIndex, vRequest in vRequests do |
||
2110 | if vRequest.mOpcode == pRequest.mOpcode |
||
2111 | and vRequest.mUserName == pRequest.mUserName then |
||
2112 | table.remove(vRequests, vIndex); |
||
2113 | break; |
||
2114 | end |
||
2115 | end |
||
2116 | end |
||
2117 | |||
2118 | return CalendarNetwork_QueueRequest(pRequest, pDelay); |
||
2119 | end |
||
2120 | |||
2121 | function CalendarNetwork_ArrayContainsArray(pArray, pSubArray) |
||
2122 | for vFieldName, vFieldValue in pSubArray do |
||
2123 | if pArray[vFieldName] ~= vFieldValue then |
||
2124 | return false; |
||
2125 | end |
||
2126 | end |
||
2127 | |||
2128 | return true; |
||
2129 | end |
||
2130 | |||
2131 | function CalendarNetwork_FindRequest(pRequest) |
||
2132 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2133 | for vIndex, vRequest in vRequests do |
||
2134 | if CalendarNetwork_ArrayContainsArray(vRequest, pRequest) then |
||
2135 | return vRequest; |
||
2136 | end |
||
2137 | end |
||
2138 | end |
||
2139 | |||
2140 | return nil; |
||
2141 | end |
||
2142 | |||
2143 | function CalendarNetwork_FindUPDRequest(pDatabaseTag, pUserName) |
||
2144 | return CalendarNetwork_FindRequest({mOpcode = pDatabaseTag.."_UPD", mUserName = pUserName}); |
||
2145 | end |
||
2146 | |||
2147 | function CalendarNetwork_CancelRedundantRFURequest(pDatabaseTag, pUserName, pDatabaseID, pFromRevision) |
||
2148 | local vOpcode = pDatabaseTag.."_RFU"; |
||
2149 | |||
2150 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2151 | for vIndex, vRequest in vRequests do |
||
2152 | if vRequest.mOpcode == vOpcode |
||
2153 | and vRequest.mUserName == pUserName then |
||
2154 | if vRequest.mDatabaseID == pDatabaseID |
||
2155 | and pFromRevision <= vRequest.mRevision then |
||
2156 | if gGroupCalendar_Settings.DebugUpdates then |
||
2157 | Calendar_DebugMessage("Removing redundant RFU for "..pDatabaseTag.." "..pUserName..","..pDatabaseID..","..pFromRevision); |
||
2158 | end |
||
2159 | |||
2160 | table.remove(vRequests, vIndex); |
||
2161 | return false; -- Return false to indicate there is no longer an RFU for this user |
||
2162 | else |
||
2163 | if gGroupCalendar_Settings.DebugUpdates then |
||
2164 | Calendar_DebugMessage("Keeping RFU request for "..pDatabaseTag.." "..pUserName..","..vRequest.mDatabaseID..","..vRequest.mRevision); |
||
2165 | Calendar_DebugMessage("Better thean "..pDatabaseTag.." "..pUserName..","..pDatabaseID..","..pFromRevision); |
||
2166 | end |
||
2167 | end |
||
2168 | |||
2169 | if gGroupCalendar_Settings.DebugUpdates then |
||
2170 | Calendar_DebugMessage("RFU for "..pDatabaseTag.." "..pUserName..","..pDatabaseID..","..pFromRevision.." already exists"); |
||
2171 | end |
||
2172 | |||
2173 | return true; -- Return true to indicate there is an RFU for this user |
||
2174 | end |
||
2175 | end |
||
2176 | end |
||
2177 | |||
2178 | return false; -- Return false to indicate no RFU for this user was found |
||
2179 | end |
||
2180 | |||
2181 | function CalendarNetwork_NeedsUpdateTimer() |
||
2182 | if gGroupCalendar_Queue.TasksDelay then |
||
2183 | return true; |
||
2184 | end |
||
2185 | |||
2186 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2187 | if table.getn(vRequests) > 0 then |
||
2188 | return true; |
||
2189 | end |
||
2190 | end |
||
2191 | |||
2192 | if table.getn(gGroupCalendar_Queue.InboundMessages) > 0 then |
||
2193 | return true; |
||
2194 | end |
||
2195 | |||
2196 | if table.getn(gGroupCalendar_Queue.OutboundMessages) > 0 then |
||
2197 | return true; |
||
2198 | end |
||
2199 | |||
2200 | return false; |
||
2201 | end |
||
2202 | |||
2203 | function CalendarNetwork_ProcessTaskQueue(pElapsed) |
||
2204 | if not gGroupCalendar_Queue.TasksDelay then |
||
2205 | return; |
||
2206 | end |
||
2207 | |||
2208 | gGroupCalendar_Queue.TasksDelay = gGroupCalendar_Queue.TasksDelay - pElapsed; |
||
2209 | gGroupCalendar_Queue.TasksElapsed = gGroupCalendar_Queue.TasksElapsed + pElapsed; |
||
2210 | |||
2211 | if gGroupCalendar_Queue.TasksDelay <= 0 then |
||
2212 | local vNumTasks = table.getn(gGroupCalendar_Queue.Tasks); |
||
2213 | local vIndex = 1; |
||
2214 | |||
2215 | gGroupCalendar_Queue.TasksDelay = nil; |
||
2216 | |||
2217 | local vLatencyStartTime; |
||
2218 | |||
2219 | if gGroupCalendar_Settings.DebugLatency then |
||
2220 | vLatencyStartTime = GetTime(); |
||
2221 | end |
||
2222 | |||
2223 | while vIndex <= vNumTasks do |
||
2224 | local vTask = gGroupCalendar_Queue.Tasks[vIndex]; |
||
2225 | |||
2226 | vTask.mDelay = vTask.mDelay - gGroupCalendar_Queue.TasksElapsed; |
||
2227 | |||
2228 | if vTask.mDelay <= 0 then |
||
2229 | table.remove(gGroupCalendar_Queue.Tasks, vIndex); |
||
2230 | vNumTasks = vNumTasks - 1; |
||
2231 | |||
2232 | -- Perform the task |
||
2233 | |||
2234 | vTask.mTaskFunc(vTask.mTaskParam); |
||
2235 | |||
2236 | else |
||
2237 | if not gGroupCalendar_Queue.TasksDelay |
||
2238 | or vTask.mDelay < gGroupCalendar_Queue.TasksDelay then |
||
2239 | gGroupCalendar_Queue.TasksDelay = vTask.mDelay; |
||
2240 | end |
||
2241 | |||
2242 | vIndex = vIndex + 1; |
||
2243 | end |
||
2244 | end |
||
2245 | |||
2246 | if gGroupCalendar_Settings.DebugLatency then |
||
2247 | local vElapsed = GetTime() - vLatencyStartTime; |
||
2248 | |||
2249 | if vElapsed > 0.1 then |
||
2250 | Calendar_DebugMessage("Tasks took "..vElapsed.."s to execute ("..vNumTasks.." tasks)"); |
||
2251 | end |
||
2252 | end |
||
2253 | |||
2254 | gGroupCalendar_Queue.TasksElapsed = 0; |
||
2255 | end |
||
2256 | end |
||
2257 | |||
2258 | function CalendarNetwork_ProcessInboundQueue(pElapsed, pCurrentTimeStamp) |
||
2259 | local vNumInboundMessages = table.getn(gGroupCalendar_Queue.InboundMessages); |
||
2260 | |||
2261 | if vNumInboundMessages > 0 then |
||
2262 | local vCollisionDetected = false; |
||
2263 | |||
2264 | gGroupCalendar_Queue.InboundDelay = gGroupCalendar_Queue.InboundDelay - pElapsed; |
||
2265 | |||
2266 | if gGroupCalendar_Queue.InboundDelay <= 0 then |
||
2267 | -- Process one message |
||
2268 | |||
2269 | local vMessage = gGroupCalendar_Queue.InboundMessages[1]; |
||
2270 | |||
2271 | table.remove(gGroupCalendar_Queue.InboundMessages, 1); |
||
2272 | |||
2273 | local vLatencyStartTime; |
||
2274 | |||
2275 | if gGroupCalendar_Settings.DebugLatency then |
||
2276 | vLatencyStartTime = GetTime(); |
||
2277 | end |
||
2278 | |||
2279 | CalendarNetwork_ProcessCommandString(vMessage.mSender, vMessage.mTrustLevel, vMessage.mMessage, pCurrentTimeStamp); |
||
2280 | |||
2281 | if gGroupCalendar_Settings.DebugLatency then |
||
2282 | local vElapsed = GetTime() - vLatencyStartTime; |
||
2283 | |||
2284 | if vElapsed > 0.1 then |
||
2285 | Calendar_DebugMessage("Inbound message took "..vElapsed.."s to process"); |
||
2286 | Calendar_DumpArray("Message", vMessage); |
||
2287 | end |
||
2288 | end |
||
2289 | |||
2290 | gGroupCalendar_Queue.InboundDelay = gCalendarNetwork_RequestDelay.InboundQueue; |
||
2291 | |||
2292 | if gGroupCalendar_Queue.InboundLastSender ~= vMessage.mSender then |
||
2293 | if gGroupCalendar_Queue.InboundTimeSinceLastMessage < gCalendarNetwork_RequestDelay.OutboundQueueGapMin then |
||
2294 | -- Collision between other senders detected |
||
2295 | |||
2296 | if gGroupCalendar_Settings.DebugQueues then |
||
2297 | Calendar_DebugMessage("Collision detected between "..gGroupCalendar_Queue.InboundLastSender.." and "..vMessage.mSender); |
||
2298 | end |
||
2299 | |||
2300 | vCollisionDetected = true; |
||
2301 | end |
||
2302 | |||
2303 | gGroupCalendar_Queue.InboundLastSender = vMessage.mSender; |
||
2304 | end |
||
2305 | |||
2306 | gGroupCalendar_Queue.InboundTimeSinceLastMessage = 0; |
||
2307 | end |
||
2308 | |||
2309 | -- Terminate processing while there are any pending inbound messages and delay further |
||
2310 | -- processing of the outbound and request queues |
||
2311 | |||
2312 | -- If there was a collision and we *weren't* part of it then increase the range to |
||
2313 | -- avoid allowing us to become a part of the next collision. This should gradually eliminate |
||
2314 | -- transmittors from the collisions until someone successfully takes over the wire. |
||
2315 | -- This probably seems really counterintuitive, but the idea is to eliminate players who |
||
2316 | -- didn't participate in a collision from attempting to try again. By doing this, each collision |
||
2317 | -- should eliminate a significant number of players from the accident, leaving only the actual |
||
2318 | -- victims to try again. The next collision will then eliminate several of those players |
||
2319 | -- until within a few seconds only one player remains and that player will then have control |
||
2320 | -- and finish his transmission. |
||
2321 | |||
2322 | local vOutboundQueueGapMin = gCalendarNetwork_RequestDelay.OutboundQueueGapMin; |
||
2323 | local vRequestQueueGapMin = gCalendarNetwork_RequestDelay.RequestQueueGapMin; |
||
2324 | |||
2325 | if vCollisionDetected |
||
2326 | and gGroupCalendar_Queue.OutboundTimeSinceLastMessage > gCalendarNetwork_RequestDelay.OutboundQueueGapMin then |
||
2327 | -- Collision detected between other players so use a longer gap to make sure |
||
2328 | -- we're not part of the next collision |
||
2329 | |||
2330 | vOutboundQueueGapMin = vOutboundQueueGapMin + gCalendarNetwork_RequestDelay.OutboundQueueGapWidth; |
||
2331 | vRequestQueueGapMin = vRequestQueueGapMin + gCalendarNetwork_RequestDelay.RequestQueueGapWidth; |
||
2332 | end |
||
2333 | |||
2334 | vRandom = math.random(); |
||
2335 | |||
2336 | if gGroupCalendar_Queue.OutboundDelay < vOutboundQueueGapMin then |
||
2337 | gGroupCalendar_Queue.OutboundDelay = vOutboundQueueGapMin + vRandom * gCalendarNetwork_RequestDelay.OutboundQueueGapWidth; |
||
2338 | end |
||
2339 | |||
2340 | if gGroupCalendar_Queue.RequestsDelay < vRequestQueueGapMin then |
||
2341 | gGroupCalendar_Queue.RequestsDelay = vRequestQueueGapMin + vRandom * gCalendarNetwork_RequestDelay.RequestQueueGapWidth; |
||
2342 | end |
||
2343 | |||
2344 | return true; |
||
2345 | end |
||
2346 | |||
2347 | return false; |
||
2348 | end |
||
2349 | |||
2350 | function CalendarNetwork_ProcessOutboundQueue(pElapsed) |
||
2351 | local vNumOutboundMessages = table.getn(gGroupCalendar_Queue.OutboundMessages); |
||
2352 | |||
2353 | if vNumOutboundMessages > 0 then |
||
2354 | gGroupCalendar_Queue.OutboundDelay = gGroupCalendar_Queue.OutboundDelay - pElapsed; |
||
2355 | |||
2356 | if gGroupCalendar_Queue.OutboundDelay <= 0 then |
||
2357 | local vLatencyStartTime; |
||
2358 | |||
2359 | if gGroupCalendar_Settings.DebugLatency then |
||
2360 | vLatencyStartTime = GetTime(); |
||
2361 | end |
||
2362 | |||
2363 | -- Send one message |
||
2364 | |||
2365 | local vMessage = gGroupCalendar_Queue.OutboundMessages[1]; |
||
2366 | |||
2367 | table.remove(gGroupCalendar_Queue.OutboundMessages, 1); |
||
2368 | |||
2369 | CalendarNetwork_SendMessage(vMessage); |
||
2370 | |||
2371 | gGroupCalendar_Queue.OutboundDelay = gCalendarNetwork_RequestDelay.OutboundQueue; |
||
2372 | |||
2373 | -- Reset the time since last message to figure out if we're part of a collision |
||
2374 | |||
2375 | gGroupCalendar_Queue.OutboundTimeSinceLastMessage = 0; |
||
2376 | |||
2377 | -- |
||
2378 | |||
2379 | if gGroupCalendar_Settings.DebugLatency then |
||
2380 | local vElapsed = GetTime() - vLatencyStartTime; |
||
2381 | |||
2382 | if vElapsed > 0.1 then |
||
2383 | Calendar_DebugMessage("Outbound message took "..vElapsed.."s to process"); |
||
2384 | Calendar_DebugMessage(vMessage); |
||
2385 | end |
||
2386 | end |
||
2387 | |||
2388 | -- Stop processing if this isn't the last outbound message, otherwise |
||
2389 | -- go ahead and allow the request queue to be processed |
||
2390 | |||
2391 | if vNumOutboundMessages == 1 then |
||
2392 | gGroupCalendar_Queue.RequestsDelay = 0; |
||
2393 | else |
||
2394 | return true; |
||
2395 | end |
||
2396 | else |
||
2397 | -- Terminate processing while there are any pending outbound messages and delay further |
||
2398 | -- processing of the request queues |
||
2399 | |||
2400 | gGroupCalendar_Queue.RequestsDelay = gCalendarNetwork_RequestDelay.RequestQueueGapMin + math.random() * gCalendarNetwork_RequestDelay.RequestQueueGapWidth; |
||
2401 | return true; |
||
2402 | end |
||
2403 | end |
||
2404 | |||
2405 | return false; |
||
2406 | end |
||
2407 | |||
2408 | GroupCalendar_cUpdateRequestOpcodes = |
||
2409 | { |
||
2410 | ["DB_UPD"] = true, |
||
2411 | ["RAT_UPD"] = true, |
||
2412 | ["DB_NOU"] = true, |
||
2413 | ["RAT_NOU"] = true |
||
2414 | }; |
||
2415 | |||
2416 | function CalendarNetwork_CanProcessRequest(pRequest) |
||
2417 | if not GroupCalendar_cUpdateRequestOpcodes[pRequest.mOpCode] then |
||
2418 | return true; |
||
2419 | end |
||
2420 | |||
2421 | if not gGroupCalendar_EnableUpdates then |
||
2422 | return false; |
||
2423 | end |
||
2424 | |||
2425 | if pRequest.mUserName then |
||
2426 | local vDatabase = EventDatabase_GetDatabase(pRequest.mUserName, false); |
||
2427 | |||
2428 | if vDatabase |
||
2429 | and vDatabase.IsPlayerOwned |
||
2430 | and not gGroupCalendar_EnableSelfUpdates then |
||
2431 | return false; |
||
2432 | end |
||
2433 | end |
||
2434 | |||
2435 | return true; |
||
2436 | end |
||
2437 | |||
2438 | function CalendarNetwork_ProcessRequestQueue(pElapsed, pSuppressProcessing) |
||
2439 | local vNumRequests = 0; |
||
2440 | |||
2441 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2442 | vNumRequests = vNumRequests + table.getn(vRequests); |
||
2443 | end |
||
2444 | |||
2445 | if vNumRequests > 0 then |
||
2446 | gGroupCalendar_Queue.RequestsDelay = gGroupCalendar_Queue.RequestsDelay - pElapsed; |
||
2447 | gGroupCalendar_Queue.RequestsElapsed = gGroupCalendar_Queue.RequestsElapsed + pElapsed; |
||
2448 | |||
2449 | if gGroupCalendar_Queue.RequestsDelay <= 0 then |
||
2450 | -- Process one request |
||
2451 | |||
2452 | local vDidProcessRequest = pSuppressProcessing; |
||
2453 | local vMinDelayForNextRequest = nil; |
||
2454 | |||
2455 | local vLatencyStartTime; |
||
2456 | local vTotalRequests = 0; |
||
2457 | |||
2458 | if gGroupCalendar_Settings.DebugLatency then |
||
2459 | vLatencyStartTime = GetTime(); |
||
2460 | end |
||
2461 | |||
2462 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2463 | local vIndex = 1; |
||
2464 | local vNumRequestsThisQueue = table.getn(vRequests); |
||
2465 | |||
2466 | vTotalRequests = vTotalRequests + vNumRequestsThisQueue; |
||
2467 | |||
2468 | while vIndex <= vNumRequestsThisQueue do |
||
2469 | local vRequest = vRequests[vIndex]; |
||
2470 | |||
2471 | if vRequest.mDelay > 0 then |
||
2472 | vRequest.mDelay = vRequest.mDelay - gGroupCalendar_Queue.RequestsElapsed; |
||
2473 | |||
2474 | if vRequest.mDelay < 0 then |
||
2475 | vRequest.mDelay = 0; |
||
2476 | end |
||
2477 | end |
||
2478 | |||
2479 | if vRequest.mDelay == 0 |
||
2480 | and not vDidProcessRequest then |
||
2481 | table.remove(vRequests, vIndex); |
||
2482 | vNumRequestsThisQueue = vNumRequestsThisQueue - 1; |
||
2483 | |||
2484 | CalendarNetwork_ProcessRequest(vRequest); |
||
2485 | |||
2486 | vDidProcessRequest = true; |
||
2487 | else |
||
2488 | if not vMinDelayForNextRequest |
||
2489 | or vRequest.mDelay < vMinDelayForNextRequest then |
||
2490 | vMinDelayForNextRequest = vRequest.mDelay; |
||
2491 | end |
||
2492 | |||
2493 | vIndex = vIndex + 1; |
||
2494 | end |
||
2495 | end -- while vIndex |
||
2496 | end -- for vPriority |
||
2497 | |||
2498 | if gGroupCalendar_Settings.DebugLatency then |
||
2499 | local vElapsed = GetTime() - vLatencyStartTime; |
||
2500 | |||
2501 | if vElapsed > 0.1 then |
||
2502 | Calendar_DebugMessage("Requests took "..vElapsed.."s to process ("..vTotalRequests.." total requests)"); |
||
2503 | end |
||
2504 | end |
||
2505 | |||
2506 | if not vMinDelayForNextRequest |
||
2507 | or vMinDelayForNextRequest < gCalendarNetwork_RequestDelay.RequestQueue then |
||
2508 | vMinDelayForNextRequest = gCalendarNetwork_RequestDelay.RequestQueue; |
||
2509 | end |
||
2510 | |||
2511 | gGroupCalendar_Queue.RequestsDelay = vMinDelayForNextRequest; |
||
2512 | gGroupCalendar_Queue.RequestsElapsed = 0; |
||
2513 | end |
||
2514 | end |
||
2515 | end |
||
2516 | |||
2517 | function CalendarNetwork_ProcessQueues(pElapsed) |
||
2518 | -- Get the current time stamp |
||
2519 | |||
2520 | local vCurrentTimeStamp = Calendar_GetCurrentLocalDateTimeStamp(); |
||
2521 | |||
2522 | -- Process tasks |
||
2523 | |||
2524 | CalendarNetwork_ProcessTaskQueue(pElapsed); |
||
2525 | |||
2526 | -- Update the collision detection counters |
||
2527 | |||
2528 | gGroupCalendar_Queue.InboundTimeSinceLastMessage = gGroupCalendar_Queue.InboundTimeSinceLastMessage + pElapsed; |
||
2529 | gGroupCalendar_Queue.OutboundTimeSinceLastMessage = gGroupCalendar_Queue.OutboundTimeSinceLastMessage + pElapsed; |
||
2530 | |||
2531 | -- Process inbound messages |
||
2532 | |||
2533 | local vSuppressRequests = false; |
||
2534 | |||
2535 | if CalendarNetwork_ProcessInboundQueue(pElapsed, vCurrentTimeStamp) then |
||
2536 | vSuppressRequests = true; |
||
2537 | |||
2538 | elseif CalendarNetwork_ProcessOutboundQueue(pElapsed) then |
||
2539 | vSuppressRequests = true; |
||
2540 | end |
||
2541 | |||
2542 | -- Process pending requests if there are no outbound messages pending |
||
2543 | |||
2544 | CalendarNetwork_ProcessRequestQueue(pElapsed, vSuppressRequests); |
||
2545 | end |
||
2546 | |||
2547 | function CalendarNetwork_ProcessRequest(pRequest) |
||
2548 | local vDatabase; |
||
2549 | |||
2550 | if pRequest.mUserName then |
||
2551 | vDatabase = EventDatabase_GetDatabase(pRequest.mUserName, false); |
||
2552 | else |
||
2553 | vDatabase = nil; |
||
2554 | end |
||
2555 | |||
2556 | if pRequest.mOpcode == "DB_UPD" then |
||
2557 | if vDatabase then -- Check for nil since the database may have gotten deleted while in the queue |
||
2558 | CalendarNetwork_SendChanges(vDatabase.Changes, "DB", vDatabase.UserName, vDatabase.IsPlayerOwned, pRequest.mRevision); |
||
2559 | end |
||
2560 | |||
2561 | elseif pRequest.mOpcode == "RAT_UPD" then |
||
2562 | if vDatabase then -- Check for nil since the database may have gotten deleted while in the queue |
||
2563 | CalendarNetwork_SendChanges(vDatabase.RSVPs, "RAT", vDatabase.UserName, vDatabase.IsPlayerOwned, pRequest.mRevision); |
||
2564 | end |
||
2565 | |||
2566 | elseif pRequest.mOpcode == "DB_NOU" then |
||
2567 | if vDatabase then -- Check for nil since the database may have gotten deleted while in the queue |
||
2568 | CalendarNetwork_DBRevisionChanged(vDatabase); |
||
2569 | end |
||
2570 | |||
2571 | elseif pRequest.mOpcode == "RAT_NOU" then |
||
2572 | if vDatabase then -- Check for nil since the database may have gotten deleted while in the queue |
||
2573 | CalendarNetwork_RSVPRevisionChanged(vDatabase); |
||
2574 | end |
||
2575 | |||
2576 | elseif pRequest.mOpcode == "DB_RFU" then |
||
2577 | local vCurrentRevision; |
||
2578 | local vAuthRevision; |
||
2579 | |||
2580 | if vDatabase and vDatabase.Changes then |
||
2581 | vCurrentRevision = vDatabase.Changes.Revision; |
||
2582 | vAuthRevision = vDatabase.Changes.AuthRevision; |
||
2583 | else |
||
2584 | vCurrentRevision = 0; |
||
2585 | vAuthRevision = nil; |
||
2586 | end |
||
2587 | |||
2588 | if vCurrentRevision < pRequest.mRevision |
||
2589 | or vCurrentRevision == 0 then |
||
2590 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix..EventDatabase_GetDBRevisionPath(pRequest.mUserName, pRequest.mDatabaseID, vCurrentRevision, vAuthRevision).."RFU"); |
||
2591 | end |
||
2592 | |||
2593 | elseif pRequest.mOpcode == "RAT_RFU" then |
||
2594 | local vCurrentRevision; |
||
2595 | local vAuthRevision; |
||
2596 | |||
2597 | if vDatabase and vDatabase.RSVPs then |
||
2598 | vCurrentRevision = vDatabase.RSVPs.Revision; |
||
2599 | vAuthRevision = vDatabase.RSVPs.AuthRevision; |
||
2600 | else |
||
2601 | vCurrentRevision = 0; |
||
2602 | vAuthRevision = nil; |
||
2603 | end |
||
2604 | |||
2605 | if vCurrentRevision < pRequest.mRevision |
||
2606 | or vCurrentRevision == 0 then |
||
2607 | CalendarNetwork_QueueOutboundMessage(gGroupCalendar_MessagePrefix..EventDatabase_GetRSVPRevisionPath(pRequest.mUserName, pRequest.mDatabaseID, vCurrentRevision, vAuthRevision).."RFU"); |
||
2608 | end |
||
2609 | |||
2610 | elseif pRequest.mOpcode == "AUTOCONFIG" then |
||
2611 | CalendarNetwork_DoAutoConfig(pRequest.mCheckDatabaseTrust); |
||
2612 | |||
2613 | elseif pRequest.mOpcode == "DBTRUST" then |
||
2614 | EventDatabase_CheckDatabaseTrust(); |
||
2615 | |||
2616 | elseif pRequest.mOpcode == "OWNEDNOTICES" then |
||
2617 | gGroupCalendar_EnableUpdates = true; |
||
2618 | gGroupCalendar_EnableSelfUpdates = true; |
||
2619 | CalendarNetwork_SendOwnedDatabaseUpdateNotices(); |
||
2620 | end |
||
2621 | end |
||
2622 | |||
2623 | function CalendarNetwork_Initialize() |
||
2624 | gGroupCalendar_Initialized = true; |
||
2625 | |||
2626 | if gGroupCalendar_Settings.DebugInit then |
||
2627 | Calendar_DebugMessage("GroupCalendar Initializing: Starting initialization"); |
||
2628 | end |
||
2629 | |||
2630 | CalendarNetwork_PlayerGuildChanged(); |
||
2631 | |||
2632 | -- Go ahead and do manual channel configuration now, automatic |
||
2633 | -- config will be handled once the player guild gets set and |
||
2634 | -- the roster gets loaded |
||
2635 | |||
2636 | if not gGroupCalendar_PlayerSettings.Channel.AutoConfig then |
||
2637 | if gGroupCalendar_Settings.DebugInit then |
||
2638 | Calendar_DebugMessage("GroupCalendar INIT: Starting up data channel (manual configuration)"); |
||
2639 | end |
||
2640 | |||
2641 | if gGroupCalendar_PlayerSettings.Channel.Name then |
||
2642 | CalendarNetwork_SetChannel( |
||
2643 | gGroupCalendar_PlayerSettings.Channel.Name, |
||
2644 | gGroupCalendar_PlayerSettings.Channel.Password); |
||
2645 | else |
||
2646 | CalendarNetwork_SetChannelStatus("Disconnected"); |
||
2647 | Calendar_DebugMessage("GroupCalendar channel is not set"); |
||
2648 | end |
||
2649 | end |
||
2650 | |||
2651 | Calendar_GetPrimaryTradeskills(); |
||
2652 | end |
||
2653 | |||
2654 | function CalendarNetwork_SendNotices() |
||
2655 | -- If trust isn't available yet just defer the notices |
||
2656 | |||
2657 | if not CalendarTrust_TrustCheckingAvailable() then |
||
2658 | gGroupCalendar_SendNoticesOnRosterUpdate = true; |
||
2659 | return; |
||
2660 | end |
||
2661 | |||
2662 | -- |
||
2663 | |||
2664 | if gGroupCalendar_Settings.DebugInit then |
||
2665 | Calendar_DebugMessage("Sending notices"); |
||
2666 | end |
||
2667 | |||
2668 | CalendarNetwork_RequestAllDatabaseUpdates(); |
||
2669 | |||
2670 | -- Request databases for trusted players who haven't sent one yet |
||
2671 | |||
2672 | if not gGroupCalendar_PlayerSettings.Security.TrustAnyone then |
||
2673 | CalendarNetwork_RequestMissingDatabases(); |
||
2674 | end |
||
2675 | |||
2676 | -- Schedule a request to send out owned database notices in two minutes |
||
2677 | |||
2678 | CalendarNetwork_QueueUniqueOpcodeRequest({mOpcode = "OWNEDNOTICES"}, gCalendarNetwork_RequestDelay.OwnedNotices); |
||
2679 | end |
||
2680 | |||
2681 | function CalendarNetwork_RequestAllDatabaseUpdates() |
||
2682 | -- Immediately send a notice of our version |
||
2683 | |||
2684 | CalendarNetwork_SendMessage(gGroupCalendar_MessagePrefix.."VER:"..gGroupCalendar_VersionString); |
||
2685 | |||
2686 | -- Immediately request updates to our own databases |
||
2687 | |||
2688 | for vRealmName, vDatabase in gGroupCalendar_Database.Databases do |
||
2689 | if EventDatabase_DatabaseIsVisible(vDatabase) |
||
2690 | and vDatabase.IsPlayerOwned then |
||
2691 | CalendarNetwork_RequestUpdate(vDatabase, vDatabase.Changes, "DB", true); |
||
2692 | CalendarNetwork_RequestUpdate(vDatabase, vDatabase.RSVPs, "RAT", true); |
||
2693 | end |
||
2694 | end |
||
2695 | |||
2696 | -- Request updates to all other databases after a delay |
||
2697 | |||
2698 | CalendarNetwork_QueueTask(CalendarNetwork_RequestExternalDatabaseUpdates, nil, gCalendarNetwork_RequestDelay.ExternalUpdateRequest, "EXTERNALUPDATE"); |
||
2699 | end |
||
2700 | |||
2701 | function CalendarNetwork_RequestExternalDatabaseUpdates() |
||
2702 | if gGroupCalendar_PlayerSettings.Security.TrustAnyone then |
||
2703 | CalendarNetwork_RequestAllUpdate(); |
||
2704 | |||
2705 | elseif gGroupCalendar_PlayerSettings.Security.TrustGuildies |
||
2706 | and gGroupCalendar_PlayerGuild then |
||
2707 | CalendarNetwork_RequestGuildUpdate(gGroupCalendar_PlayerGuild, gGroupCalendar_PlayerSettings.Security.MinTrustedRank); |
||
2708 | end |
||
2709 | |||
2710 | if not gGroupCalendar_PlayerSettings.Security.TrustAnyone then |
||
2711 | for vRealmName, vDatabase in gGroupCalendar_Database.Databases do |
||
2712 | if EventDatabase_DatabaseIsVisible(vDatabase) then |
||
2713 | if not vDatabase.IsPlayerOwned |
||
2714 | and (not gGroupCalendar_PlayerSettings.Security.TrustGuildies |
||
2715 | or vDatabase.Guild ~= gGroupCalendar_PlayerGuild) then |
||
2716 | CalendarNetwork_RequestUpdate(vDatabase, vDatabase.Changes, "DB", false); |
||
2717 | CalendarNetwork_RequestUpdate(vDatabase, vDatabase.RSVPs, "RAT", false); |
||
2718 | end |
||
2719 | end |
||
2720 | end |
||
2721 | end |
||
2722 | end |
||
2723 | |||
2724 | function CalendarNetwork_SendOwnedDatabaseUpdateNotices() |
||
2725 | for vRealmName, vDatabase in gGroupCalendar_Database.Databases do |
||
2726 | if EventDatabase_DatabaseIsVisible(vDatabase) |
||
2727 | and vDatabase.IsPlayerOwned then |
||
2728 | if not CalendarChanges_IsEmpty(vDatabase.Changes) then |
||
2729 | CalendarNetwork_DBRevisionChanged(vDatabase); |
||
2730 | end |
||
2731 | |||
2732 | if not CalendarChanges_IsEmpty(vDatabase.RSVPs) then |
||
2733 | CalendarNetwork_RSVPRevisionChanged(vDatabase); |
||
2734 | end |
||
2735 | end |
||
2736 | end |
||
2737 | end |
||
2738 | |||
2739 | gCalendarNetwork_GuildMemberRankCache = nil; |
||
2740 | |||
2741 | function CalendarNetwork_FlushCaches() |
||
2742 | gCalendarNetwork_GuildMemberRankCache = nil; |
||
2743 | gCalendarNetwork_UserTrustCache = {}; |
||
2744 | end |
||
2745 | |||
2746 | function CalendarNetwork_GetGuildRosterCache() |
||
2747 | if gCalendarNetwork_GuildMemberRankCache then |
||
2748 | return gCalendarNetwork_GuildMemberRankCache; |
||
2749 | end |
||
2750 | |||
2751 | -- Clear the cache |
||
2752 | |||
2753 | gCalendarNetwork_GuildMemberRankCache = {}; |
||
2754 | |||
2755 | -- Scan the roster and collect the info |
||
2756 | |||
2757 | local vNumGuildMembers = GetNumGuildMembers(true); |
||
2758 | |||
2759 | for vIndex = 1, vNumGuildMembers do |
||
2760 | local vName, vRank, vRankIndex, vLevel, vClass, vZone, vNote, vOfficerNote, vOnline = GetGuildRosterInfo(vIndex); |
||
2761 | |||
2762 | if vName then -- Have to check for name in case a guild member gets booted while querying the roster |
||
2763 | local vMemberInfo = |
||
2764 | { |
||
2765 | Name = vName, |
||
2766 | RankIndex = vRankIndex, |
||
2767 | Level = vLevel, |
||
2768 | Class = vClass, |
||
2769 | Zone = vZone, |
||
2770 | OfficerNote = vOfficerNote, |
||
2771 | Online = vOnline |
||
2772 | }; |
||
2773 | |||
2774 | gCalendarNetwork_GuildMemberRankCache[strupper(vName)] = vMemberInfo; |
||
2775 | end |
||
2776 | end |
||
2777 | |||
2778 | -- Dump any cached trust info |
||
2779 | |||
2780 | gCalendarNetwork_UserTrustCache = {}; |
||
2781 | |||
2782 | return gCalendarNetwork_GuildMemberRankCache; |
||
2783 | end |
||
2784 | |||
2785 | local gGroupCalendar_SentLoadGuildRoster = false; |
||
2786 | |||
2787 | function CalendarNetwork_LoadGuildRosterTask() |
||
2788 | if IsInGuild() then |
||
2789 | GuildRoster(); |
||
2790 | end |
||
2791 | |||
2792 | -- Schedule another task to load the roster again |
||
2793 | -- in four minutes |
||
2794 | |||
2795 | CalendarNetwork_QueueTask( |
||
2796 | CalendarNetwork_LoadGuildRosterTask, nil, |
||
2797 | 240, "GUILDROSTER"); |
||
2798 | end |
||
2799 | |||
2800 | function CalendarNetwork_LoadGuildRoster() |
||
2801 | if not IsInGuild() |
||
2802 | or GetNumGuildMembers() > 0 |
||
2803 | or gGroupCalendar_SentLoadGuildRoster then |
||
2804 | return; |
||
2805 | end |
||
2806 | |||
2807 | gGroupCalendar_SentLoadGuildRoster = true; |
||
2808 | |||
2809 | if gGroupCalendar_Settings.DebugInit then |
||
2810 | Calendar_DebugMessage("CalendarNetwork_LoadGuildRoster: Loading"); |
||
2811 | end |
||
2812 | |||
2813 | CalendarNetwork_LoadGuildRosterTask(); |
||
2814 | end |
||
2815 | |||
2816 | function CalendarNetwork_UserIsInSameGuild(pUserName) |
||
2817 | if not IsInGuild() then |
||
2818 | return false, nil; |
||
2819 | end |
||
2820 | |||
2821 | -- Build the roster |
||
2822 | |||
2823 | if GetNumGuildMembers() == 0 then |
||
2824 | CalendarNetwork_LoadGuildRoster(); |
||
2825 | return false, nil; -- have to return false for now since we don't really know |
||
2826 | end |
||
2827 | |||
2828 | -- Search for the member |
||
2829 | |||
2830 | local vUpperUserName = strupper(pUserName); |
||
2831 | local vRosterCache = CalendarNetwork_GetGuildRosterCache(); |
||
2832 | local vMemberInfo = vRosterCache[vUpperUserName]; |
||
2833 | |||
2834 | if not vMemberInfo then |
||
2835 | return false, nil; |
||
2836 | end |
||
2837 | |||
2838 | return true, vMemberInfo.RankIndex; |
||
2839 | end |
||
2840 | |||
2841 | function CalendarNetwork_SendAllRevisionNotices() |
||
2842 | -- Use the same delay for all the requests so that the requests will all go out together |
||
2843 | -- once they start getting processed |
||
2844 | |||
2845 | local vDelay = gCalendarNetwork_RequestDelay.ProxyNOUMin + math.random() * gCalendarNetwork_RequestDelay.ProxyNOURange; |
||
2846 | local vOwnedDelay = math.random() * gCalendarNetwork_RequestDelay.OwnedNOURange; |
||
2847 | |||
2848 | for vRealmName, vDatabase in gGroupCalendar_Database.Databases do |
||
2849 | if EventDatabase_DatabaseIsVisible(vDatabase) then |
||
2850 | local vRequest = {mOpcode = "DB_NOU", mUserName = vDatabase.UserName}; |
||
2851 | |||
2852 | if vDatabase.IsPlayerOwned then |
||
2853 | CalendarNetwork_QueueUniqueUserRequest(vRequest, vOwnedDelay); |
||
2854 | else |
||
2855 | CalendarNetwork_QueueUniqueUserRequest(vRequest, vDelay); |
||
2856 | end |
||
2857 | |||
2858 | local vRequest = {mOpcode = "RAT_NOU", mUserName = vDatabase.UserName}; |
||
2859 | |||
2860 | if vDatabase.IsPlayerOwned then |
||
2861 | CalendarNetwork_QueueUniqueUserRequest(vRequest, vOwnedDelay); |
||
2862 | else |
||
2863 | CalendarNetwork_QueueUniqueUserRequest(vRequest, vDelay); |
||
2864 | end |
||
2865 | end |
||
2866 | end |
||
2867 | end |
||
2868 | |||
2869 | function CalendarNetwork_CancelRedundantUPDRequests(pChanges, pDatabaseTag, pUserName, pDatabaseID, pRevision, pSinceRevision) |
||
2870 | local vOpcode = pDatabaseTag.."_UPD"; |
||
2871 | |||
2872 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2873 | for vIndex, vRequest in vRequests do |
||
2874 | if vRequest.mOpcode == vOpcode |
||
2875 | and vRequest.mUserName == pUserName then |
||
2876 | -- Theirs is better if: |
||
2877 | -- - Their database ID is higher |
||
2878 | -- - Their database ID is the same and |
||
2879 | -- - Their fromRevision is lower or the same |
||
2880 | -- - Their toRevision is higher or the same |
||
2881 | |||
2882 | if pDatabaseID > vRequest.mDatabaseID |
||
2883 | or (pDatabaseID == vRequest.mDatabaseID |
||
2884 | and pSinceRevision <= vRequest.mRevision |
||
2885 | and (not pChanges or pRevision >= pChanges.Revision)) then |
||
2886 | if gGroupCalendar_Settings.DebugQueues then |
||
2887 | Calendar_DebugMessage("Removing UPD request for "..pDatabaseTag.." "..pUserName..","..pDatabaseID..","..pSinceRevision.." to "..pRevision); |
||
2888 | end |
||
2889 | |||
2890 | table.remove(vRequests, vIndex); |
||
2891 | else |
||
2892 | if gGroupCalendar_Settings.DebugQueues then |
||
2893 | Calendar_DebugMessage("Keeping UPD request for "..pDatabaseTag.." "..pUserName..","..vRequest.mDatabaseID..","..vRequest.mRevision.." to "..pChanges.Revision); |
||
2894 | Calendar_DebugMessage("Better thean "..pDatabaseTag.." "..pUserName..","..pDatabaseID..","..pSinceRevision.." to "..pRevision); |
||
2895 | end |
||
2896 | end |
||
2897 | |||
2898 | return; |
||
2899 | end |
||
2900 | end -- for vIndex |
||
2901 | end -- for vPriority |
||
2902 | end |
||
2903 | |||
2904 | function CalendarNetwork_CancelRedundantNOURequests(pChanges, pDatabaseTag, pSender, pUserName, pDatabaseID, pRevision) |
||
2905 | local vOpcode = pDatabaseTag.."_NOU"; |
||
2906 | |||
2907 | for vPriority, vRequests in gGroupCalendar_Queue.Requests do |
||
2908 | for vIndex, vRequest in vRequests do |
||
2909 | if vRequest.mOpcode == vOpcode |
||
2910 | and vRequest.mUserName == pUserName then |
||
2911 | -- Cancel our update if the revision they're advertising is equal |
||
2912 | -- to or better than ours or if they're the owner |
||
2913 | |||
2914 | local vTheirsIsBetter; |
||
2915 | |||
2916 | if pSender == pUserName then |
||
2917 | vTheirsIsBetter = true; |
||
2918 | else |
||
2919 | vTheirsIsBetter = not pChanges |
||
2920 | or pDatabaseID > pChanges.ID |
||
2921 | or (pDatabaseID == pChanges.ID and pRevision >= pChanges.Revision); |
||
2922 | end |
||
2923 | |||
2924 | if vTheirsIsBetter then |
||
2925 | if gGroupCalendar_Settings.DebugQueues then |
||
2926 | Calendar_DebugMessage("Removing NOU request for "..pDatabaseTag.." "..pUserName..","..pDatabaseID..","..pRevision); |
||
2927 | end |
||
2928 | |||
2929 | table.remove(vRequests, vIndex); |
||
2930 | else |
||
2931 | if gGroupCalendar_Settings.DebugQueues then |
||
2932 | Calendar_DebugMessage("Keeping NOU request for "..pDatabaseTag.." "..pUserName..","..pChanges.ID..","..pChanges.Revision); |
||
2933 | Calendar_DebugMessage("Better than "..pDatabaseTag.." "..pUserName..","..pDatabaseID..","..pRevision); |
||
2934 | end |
||
2935 | end |
||
2936 | |||
2937 | return; |
||
2938 | end |
||
2939 | end -- for vIndex |
||
2940 | end -- for vPriority |
||
2941 | end |
||
2942 | |||
2943 | function CalendarNetwork_SendMessage(pMessage) |
||
2944 | -- Just leave if there's no channel to communicate on |
||
2945 | |||
2946 | if not gGroupCalendar_Channel.ID then |
||
2947 | return; |
||
2948 | end |
||
2949 | |||
2950 | local vSavedAutoClearAFK = GetCVar("autoClearAFK"); |
||
2951 | SetCVar("autoClearAFK", 0); |
||
2952 | |||
2953 | SendChatMessage(Calendar_EscapeChatString(pMessage), "CHANNEL", nil, gGroupCalendar_Channel.ID); |
||
2954 | |||
2955 | SetCVar("autoClearAFK", vSavedAutoClearAFK); |
||
2956 | end |
||
2957 | |||
2958 | function CalendarNetwork_ChannelMessageReceived(pSender, pMessage) |
||
2959 | local vTrustLevel = CalendarTrust_GetUserTrustLevel(pSender); |
||
2960 | |||
2961 | if vTrustLevel > 0 then |
||
2962 | CalendarNetwork_QueueInboundMessage(pSender, vTrustLevel, pMessage); |
||
2963 | else |
||
2964 | if gGroupCalendar_Settings.DebugTrust then |
||
2965 | Calendar_DebugMessage("ChannelMessageReceived: "..pSender.." is not trusted"); |
||
2966 | end |
||
2967 | end |
||
2968 | end |
||
2969 | |||
2970 | function CalendarNetwork_GetGuildMemberIndex(pPlayerName) |
||
2971 | local vUpperUserName = strupper(pPlayerName); |
||
2972 | local vNumGuildMembers = GetNumGuildMembers(true); |
||
2973 | |||
2974 | for vIndex = 1, vNumGuildMembers do |
||
2975 | local vName = GetGuildRosterInfo(vIndex); |
||
2976 | |||
2977 | if strupper(vName) == vUpperUserName then |
||
2978 | return vIndex; |
||
2979 | end |
||
2980 | end |
||
2981 | |||
2982 | return nil; |
||
2983 | end |
||
2984 | |||
2985 | function CalendarNetwork_SetAutoConfigData(pPlayerName) |
||
2986 | if not CanEditPublicNote() |
||
2987 | or not gGroupCalendar_PlayerSettings.Channel.Name then |
||
2988 | return false; |
||
2989 | end |
||
2990 | |||
2991 | local vMemberIndex = CalendarNetwork_GetGuildMemberIndex(pPlayerName); |
||
2992 | |||
2993 | if not vMemberIndex then |
||
2994 | return false; |
||
2995 | end |
||
2996 | |||
2997 | CalendarNetwork_RemoveAllAutoConfigData(pPlayerName); |
||
2998 | |||
2999 | local vNote = "["..gGroupCalendar_MessagePrefix.."C:"..gGroupCalendar_PlayerSettings.Channel.Name; |
||
3000 | |||
3001 | if gGroupCalendar_PlayerSettings.Channel.Password then |
||
3002 | vNote = vNote..","..gGroupCalendar_PlayerSettings.Channel.Password |
||
3003 | end |
||
3004 | |||
3005 | -- Add the trust group |
||
3006 | |||
3007 | local vTrustGroup = CalendarTrust_GetCurrentTrustGroup(); |
||
3008 | |||
3009 | vNote = vNote.."/T:"..vTrustGroup; |
||
3010 | |||
3011 | -- Add the trust rank |
||
3012 | |||
3013 | if gGroupCalendar_PlayerSettings.Security.TrustGuildies |
||
3014 | and gGroupCalendar_PlayerSettings.Security.MinTrustedRank then |
||
3015 | vNote = vNote..","..gGroupCalendar_PlayerSettings.Security.MinTrustedRank; |
||
3016 | end |
||
3017 | |||
3018 | vNote = vNote.."]"; |
||
3019 | |||
3020 | if gGroupCalendar_Settings.DebugConfig then |
||
3021 | Calendar_DebugMessage("Setting auto-config data on player "..pPlayerName); |
||
3022 | end |
||
3023 | |||
3024 | GuildRosterSetPublicNote(vMemberIndex, vNote); |
||
3025 | |||
3026 | return true; |
||
3027 | end |
||
3028 | |||
3029 | function CalendarNetwork_RemoveAllAutoConfigData(pExcludePlayerName) |
||
3030 | -- Remove it from the GuildInfoText |
||
3031 | |||
3032 | local vGuildInfoText = GetGuildInfoText(); |
||
3033 | local vStartIndex, vEndIndex = string.find(vGuildInfoText, "%["..gGroupCalendar_MessagePrefix.."[^%]]+%]"); |
||
3034 | |||
3035 | if vStartIndex then |
||
3036 | vGuildInfoText = string.sub(vGuildInfoText, 1, vStartIndex - 1)..string.sub(vGuildInfoText, vEndIndex + 1); |
||
3037 | SetGuildInfoText(vGuildInfoText); |
||
3038 | end |
||
3039 | |||
3040 | -- Remove it from player notes |
||
3041 | |||
3042 | local vIndex = CalendarNetwork_FindAutoConfigData(nil, pExcludePlayerName); |
||
3043 | |||
3044 | while vIndex do |
||
3045 | CalendarNetwork_RemoveAutoConfigData(vIndex); |
||
3046 | vIndex = CalendarNetwork_FindAutoConfigData(vIndex + 1, pExcludePlayerName); |
||
3047 | end |
||
3048 | end |
||
3049 | |||
3050 | function CalendarNetwork_RemoveAutoConfigData(pMemberIndex) |
||
3051 | if not pMemberIndex then |
||
3052 | Calendar_DebugMessage("CalendarNetwork_RemoveAutoConfigData: nil index"); |
||
3053 | return; |
||
3054 | end |
||
3055 | |||
3056 | local vName, vNote = CalendarNetwork_GetGuildPublicNote(pMemberIndex); |
||
3057 | |||
3058 | if not vNote then |
||
3059 | return false; |
||
3060 | end |
||
3061 | |||
3062 | if gGroupCalendar_Settings.DebugConfig then |
||
3063 | Calendar_DebugMessage("Removing auto-config data from player "..vName); |
||
3064 | end |
||
3065 | |||
3066 | local vPatternString = "%["..gGroupCalendar_MessagePrefix0.."[^%]]+%]"; |
||
3067 | |||
3068 | vNote = string.gsub(vNote, vPatternString, ""); |
||
3069 | |||
3070 | GuildRosterSetPublicNote(pMemberIndex, vNote); |
||
3071 | |||
3072 | return true; |
||
3073 | end |
||
3074 | |||
3075 | function CalendarNetwork_GetGuildPublicNote(pMemberIndex) |
||
3076 | local vName, vRank, vRankIndex, vLevel, vClass, vZone, vNote, vOfficerNote, vOnline = GetGuildRosterInfo(pMemberIndex); |
||
3077 | |||
3078 | return vName, vNote; |
||
3079 | end |
||
3080 | |||
3081 | function CalendarNetwork_GetAutoConfigData() |
||
3082 | local vGuildInfoText = GetGuildInfoText(); |
||
3083 | local vConfigSource = GroupCalendar_cGuildInfoConfigSource; |
||
3084 | |||
3085 | local vStartIndex, vEndIndex, vConfigString = string.find(vGuildInfoText, "%[("..gGroupCalendar_MessagePrefix.."[^%]]+)%]"); |
||
3086 | |||
3087 | if not vStartIndex then |
||
3088 | local vIndex = CalendarNetwork_FindAutoConfigData(); |
||
3089 | |||
3090 | if not vIndex then |
||
3091 | return nil; |
||
3092 | end |
||
3093 | |||
3094 | local vName, vNote = CalendarNetwork_GetGuildPublicNote(vIndex); |
||
3095 | |||
3096 | if not vNote then |
||
3097 | return nil; |
||
3098 | end |
||
3099 | |||
3100 | vStartIndex, vEndIndex, vConfigString = string.find(vNote, "%[("..gGroupCalendar_MessagePrefix.."[^%]]+)%]"); |
||
3101 | |||
3102 | if not vStartIndex then |
||
3103 | return nil; |
||
3104 | end |
||
3105 | |||
3106 | vConfigSource = vName; |
||
3107 | end |
||
3108 | |||
3109 | return CalendarNetwork_ParseCommandString(vConfigString), vConfigSource; |
||
3110 | end |
||
3111 | |||
3112 | function CalendarNetwork_FindAutoConfigData(pStartingIndex, pExcludePlayerName) |
||
3113 | -- Build the roster |
||
3114 | |||
3115 | if GetNumGuildMembers() == 0 then |
||
3116 | CalendarNetwork_LoadGuildRoster(); |
||
3117 | return nil; |
||
3118 | end |
||
3119 | |||
3120 | -- Search for the member |
||
3121 | |||
3122 | local vNumGuildMembers = GetNumGuildMembers(true); |
||
3123 | local vStartingIndex; |
||
3124 | |||
3125 | if pStartingIndex then |
||
3126 | vStartingIndex = pStartingIndex; |
||
3127 | else |
||
3128 | vStartingIndex = 1; |
||
3129 | end |
||
3130 | |||
3131 | for vIndex = vStartingIndex, vNumGuildMembers do |
||
3132 | local vName, vNote = CalendarNetwork_GetGuildPublicNote(vIndex); |
||
3133 | |||
3134 | if vNote |
||
3135 | and (not pExcludePlayerName or string.lower(vName) ~= string.lower(pExcludePlayerName)) |
||
3136 | and strfind(vNote, "%["..gGroupCalendar_MessagePrefix0) then |
||
3137 | if gGroupCalendar_Settings.DebugConfig then |
||
3138 | Calendar_DebugMessage("Found auto-config data on player "..vName); |
||
3139 | end |
||
3140 | |||
3141 | return vIndex, vName; |
||
3142 | end |
||
3143 | end |
||
3144 | |||
3145 | return nil; |
||
3146 | end |
||
3147 | |||
3148 | function CalendarNetwork_ScheduleCheckDatabaseTrust(pDelay) |
||
3149 | CalendarNetwork_QueueUniqueOpcodeRequest({mOpcode = "DBTRUST"}, pDelay); |
||
3150 | end |
||
3151 | |||
3152 | function CalendarNetwork_ScheduleAutoConfig(pDelay, pCheckDatabaseTrust) |
||
3153 | if gGroupCalendar_Channel.Disconnected then |
||
3154 | return; |
||
3155 | end |
||
3156 | |||
3157 | local vRequest = CalendarNetwork_FindRequest({mOpcode = "AUTOCONFIG"}); |
||
3158 | |||
3159 | if vRequest then |
||
3160 | if gGroupCalendar_Settings.DebugInit then |
||
3161 | Calendar_DebugMessage("CalendarNetwork_ScheduleAutoConfig: Rescheduling existing request"); |
||
3162 | end |
||
3163 | |||
3164 | if pDelay < vRequest.mDelay then |
||
3165 | vRequest.mDelay = pDelay; |
||
3166 | end |
||
3167 | |||
3168 | if pCheckDatabaseTrust then |
||
3169 | vRequest.mCheckDatabaseTrust = true; |
||
3170 | end |
||
3171 | else |
||
3172 | if gGroupCalendar_Settings.DebugInit then |
||
3173 | Calendar_DebugMessage("CalendarNetwork_ScheduleAutoConfig: Scheduling request"); |
||
3174 | end |
||
3175 | |||
3176 | CalendarNetwork_QueueRequest({mOpcode = "AUTOCONFIG", mCheckDatabaseTrust = pCheckDatabaseTrust}, pDelay); |
||
3177 | end |
||
3178 | end |
||
3179 | |||
3180 | function CalendarNetwork_DoAutoConfig(pCheckDatabaseTrust) |
||
3181 | if gGroupCalendar_Settings.DebugInit then |
||
3182 | Calendar_DebugMessage("CalendarNetwork_DoAutoConfig: Performing auto-config"); |
||
3183 | end |
||
3184 | |||
3185 | local vCommand, vConfigSource = CalendarNetwork_GetAutoConfigData(); |
||
3186 | |||
3187 | if not vCommand then |
||
3188 | CalendarNetwork_SetChannelStatus("Error", GroupCalendar_cAutoConfigNotFound); |
||
3189 | return false; |
||
3190 | end |
||
3191 | |||
3192 | local vChannel = nil; |
||
3193 | local vPassword = nil; |
||
3194 | local vMinTrustedRank = nil; |
||
3195 | local vTrustGroup = nil; |
||
3196 | |||
3197 | while vCommand[1] ~= nil do |
||
3198 | local vOpcode = vCommand[1].opcode; |
||
3199 | local vOperands = vCommand[1].operands; |
||
3200 | |||
3201 | table.remove(vCommand, 1); |
||
3202 | |||
3203 | if vOpcode == "CHN" |
||
3204 | or vOpcode == "C" then |
||
3205 | vChannel = vOperands[1]; |
||
3206 | vPassword = vOperands[2]; |
||
3207 | |||
3208 | elseif vOpcode == "RNK" then |
||
3209 | vMinTrustedRank = tonumber(vOperands[1]); |
||
3210 | elseif vOpcode == "T" then |
||
3211 | vTrustGroup = tonumber(vOperands[1]); |
||
3212 | vMinTrustedRank = tonumber(vOperands[2]); |
||
3213 | end |
||
3214 | end |
||
3215 | |||
3216 | local vAutoPlayerChanged = gGroupCalendar_Channel.AutoPlayer ~= vConfigSource; |
||
3217 | |||
3218 | gGroupCalendar_Channel.AutoPlayer = vConfigSource; |
||
3219 | |||
3220 | if vAutoPlayerChanged then |
||
3221 | GroupCalendar_ChannelChanged(); -- Send out a change notice just so the calendar knows the player changed |
||
3222 | end |
||
3223 | |||
3224 | CalendarNetwork_SetChannel(vChannel, vPassword); |
||
3225 | |||
3226 | -- Update the trust settings |
||
3227 | |||
3228 | local vTrustChanged = false; |
||
3229 | local vCurrentTrustGroup = CalendarTrust_GetCurrentTrustGroup(); |
||
3230 | |||
3231 | if vTrustGroup ~= nil then |
||
3232 | if vCurrentTrustGroup ~= vTrustGroup then |
||
3233 | vTrustChanged = true; |
||
3234 | end |
||
3235 | else |
||
3236 | vTrustGroup = vCurrentTrustGroup; |
||
3237 | end |
||
3238 | |||
3239 | if vMinTrustedRank ~= nil then |
||
3240 | if gGroupCalendar_PlayerSettings.Security.MinTrustedRank ~= vMinTrustedRank then |
||
3241 | vTrustChanged = true; |
||
3242 | end |
||
3243 | else |
||
3244 | vMinTrustedRank = gGroupCalendar_PlayerSettings.Security.MinTrustedRank; |
||
3245 | end |
||
3246 | |||
3247 | if vTrustChanged then |
||
3248 | CalendarTrust_SetCurrentTrustGroup(vTrustGroup, vMinTrustedRank); |
||
3249 | elseif pCheckDatabaseTrust then |
||
3250 | EventDatabase_CheckDatabaseTrust(); |
||
3251 | end |
||
3252 | |||
3253 | return true; |
||
3254 | end |
||
3255 | |||
3256 | function CalendarTrust_GetCurrentTrustGroup() |
||
3257 | if gGroupCalendar_PlayerSettings.Security.TrustAnyone then |
||
3258 | return 2; |
||
3259 | elseif gGroupCalendar_PlayerSettings.Security.TrustGuildies then |
||
3260 | return 1; |
||
3261 | else |
||
3262 | return 0; |
||
3263 | end |
||
3264 | end |
||
3265 | |||
3266 | function CalendarTrust_SetCurrentTrustGroup(pTrustGroup, pMinRank) |
||
3267 | if pTrustGroup == 2 then |
||
3268 | gGroupCalendar_PlayerSettings.Security.TrustAnyone = true; |
||
3269 | gGroupCalendar_PlayerSettings.Security.TrustGuildies = false; |
||
3270 | elseif pTrustGroup == 1 then |
||
3271 | gGroupCalendar_PlayerSettings.Security.TrustAnyone = false; |
||
3272 | gGroupCalendar_PlayerSettings.Security.TrustGuildies = true; |
||
3273 | else |
||
3274 | gGroupCalendar_PlayerSettings.Security.TrustAnyone = false; |
||
3275 | gGroupCalendar_PlayerSettings.Security.TrustGuildies = false; |
||
3276 | end |
||
3277 | |||
3278 | gGroupCalendar_PlayerSettings.Security.MinTrustedRank = pMinRank; |
||
3279 | |||
3280 | CalendarTrust_TrustSettingsChanged(); |
||
3281 | end |
||
3282 | |||
3283 | function CalendarTrust_TrustSettingsChanged() |
||
3284 | CalendarNetwork_FlushCaches(); |
||
3285 | |||
3286 | EventDatabase_CheckDatabaseTrust(); -- Delete databases owned by players we no longer trust |
||
3287 | CalendarNetwork_RequestMissingDatabases(); -- Request databases for newly trusted players |
||
3288 | |||
3289 | if gGroupCalendar_PlayerSettings.Security.TrustAnyone then |
||
3290 | CalendarNetwork_RequestAllUpdate(); |
||
3291 | else |
||
3292 | if gGroupCalendar_PlayerSettings.Security.TrustGuildies |
||
3293 | and gGroupCalendar_PlayerGuild then |
||
3294 | CalendarNetwork_RequestGuildUpdate(gGroupCalendar_PlayerGuild, gGroupCalendar_PlayerSettings.Security.MinTrustedRank); |
||
3295 | end |
||
3296 | end |
||
3297 | |||
3298 | CalendarNetwork_SendAllRevisionNotices(); -- Send out revision notices since trusted players may want to know now |
||
3299 | end |
||
3300 | |||
3301 | function CalendarTrust_TrustCheckingAvailable() |
||
3302 | if not gGroupCalendar_PlayerSettings.Security.TrustGuildies then |
||
3303 | return true; |
||
3304 | end |
||
3305 | |||
3306 | -- Doesn't matter if they're not in a guild |
||
3307 | |||
3308 | if not IsInGuild() then |
||
3309 | return true; |
||
3310 | end |
||
3311 | |||
3312 | -- If trust is guild members only then verify that the roster has been loaded |
||
3313 | |||
3314 | return GetNumGuildMembers() > 0; |
||
3315 | end |
||
3316 | |||
3317 | function CalendarTrust_GetUserTrustLevel(pUserName) |
||
3318 | local vUserTrustInfo = gCalendarNetwork_UserTrustCache[pUserName]; |
||
3319 | |||
3320 | if not vUserTrustInfo then |
||
3321 | vUserTrustInfo = {}; |
||
3322 | vUserTrustInfo.mTrustLevel = CalendarTrust_CalcUserTrust(pUserName); |
||
3323 | gCalendarNetwork_UserTrustCache[pUserName] = vUserTrustInfo; |
||
3324 | end |
||
3325 | |||
3326 | return vUserTrustInfo.mTrustLevel; |
||
3327 | end |
||
3328 | |||
3329 | function CalendarTrust_UserIsTrusted(pUserName) |
||
3330 | return CalendarTrust_GetUserTrustLevel(pUserName) == 2; |
||
3331 | end |
||
3332 | |||
3333 | function CalendarTrust_UserIsTrustedForRSVPs(pUserName) |
||
3334 | return CalendarTrust_GetUserTrustLevel(pUserName) >= 1; |
||
3335 | end |
||
3336 | |||
3337 | function CalendarTrust_CalcUserTrust(pUserName) |
||
3338 | -- If the user is one of our own characters, then trust them completely |
||
3339 | |||
3340 | local vDatabase = EventDatabase_GetDatabase(pUserName, false); |
||
3341 | |||
3342 | if vDatabase |
||
3343 | and vDatabase.IsPlayerOwned then |
||
3344 | if gGroupCalendar_Settings.DebugTrust then |
||
3345 | Calendar_DebugMessage("CalendarTrust_CalcUserTrust: Implicit trust for "..pUserName); |
||
3346 | end |
||
3347 | |||
3348 | return 2; |
||
3349 | end |
||
3350 | |||
3351 | local vPlayerSecurity = gGroupCalendar_PlayerSettings.Security.Player[pUserName]; |
||
3352 | |||
3353 | -- See if they're explicity allowed/forbidden |
||
3354 | |||
3355 | if vPlayerSecurity ~= nil then |
||
3356 | if vPlayerSecurity == 1 then |
||
3357 | -- Trusted |
||
3358 | |||
3359 | if gGroupCalendar_Settings.DebugTrust then |
||
3360 | Calendar_DebugMessage("CalendarTrust_CalcUserTrust: Explicit trust for "..pUserName); |
||
3361 | end |
||
3362 | |||
3363 | return 2; |
||
3364 | elseif vPlayerSecurity == 2 then |
||
3365 | -- Excluded |
||
3366 | |||
3367 | if gGroupCalendar_Settings.DebugTrust then |
||
3368 | Calendar_DebugMessage("CalendarTrust_CalcUserTrust: "..pUserName.." explicity excluded"); |
||
3369 | end |
||
3370 | |||
3371 | return 0; |
||
3372 | else |
||
3373 | Calendar_DebugMessage("GroupCalendar: Unknown player security setting of "..vPlayerSecurity.." for "..pUserName); |
||
3374 | end |
||
3375 | end |
||
3376 | |||
3377 | -- Return true if we'll allow anyone in the channel |
||
3378 | |||
3379 | if gGroupCalendar_PlayerSettings.Security.TrustAnyone then |
||
3380 | if gGroupCalendar_Settings.DebugTrust then |
||
3381 | Calendar_DebugMessage("CalendarTrust_CalcUserTrust: "..pUserName.." trusted (all trusted)"); |
||
3382 | end |
||
3383 | |||
3384 | return 2; |
||
3385 | end |
||
3386 | |||
3387 | -- Return true if they're in the same guild and of sufficient rank |
||
3388 | |||
3389 | if gGroupCalendar_PlayerSettings.Security.TrustGuildies then |
||
3390 | local vIsInGuild, vGuildRank = CalendarNetwork_UserIsInSameGuild(pUserName); |
||
3391 | |||
3392 | if vIsInGuild then |
||
3393 | if not gGroupCalendar_PlayerSettings.Security.MinTrustedRank |
||
3394 | or vGuildRank <= gGroupCalendar_PlayerSettings.Security.MinTrustedRank then |
||
3395 | if gGroupCalendar_Settings.DebugTrust then |
||
3396 | Calendar_DebugMessage("CalendarTrust_CalcUserTrust: "..pUserName.." trusted (guild member)"); |
||
3397 | end |
||
3398 | |||
3399 | return 2; |
||
3400 | else |
||
3401 | if gGroupCalendar_Settings.DebugTrust then |
||
3402 | Calendar_DebugMessage("CalendarTrust_CalcUserTrust: "..pUserName.." partially trusted (guild member)"); |
||
3403 | end |
||
3404 | |||
3405 | return 1; |
||
3406 | end |
||
3407 | end |
||
3408 | end |
||
3409 | |||
3410 | -- Failed all tests |
||
3411 | |||
3412 | if gGroupCalendar_Settings.DebugTrust then |
||
3413 | Calendar_DebugMessage("CalendarTrust_CalcUserTrust: "..pUserName.." not trusted (all tests failed)"); |
||
3414 | end |
||
3415 | |||
3416 | return 0; |
||
3417 | end |
||
3418 | |||
3419 | function CalendarTrust_GetNumTrustedPlayers(pTrustSetting) |
||
3420 | local vNumPlayers = 0; |
||
3421 | |||
3422 | for vPlayerName, vPlayerSecurity in gGroupCalendar_PlayerSettings.Security.Player do |
||
3423 | if vPlayerSecurity == pTrustSetting then |
||
3424 | vNumPlayers = vNumPlayers + 1; |
||
3425 | end |
||
3426 | end |
||
3427 | |||
3428 | return vNumPlayers; |
||
3429 | end |
||
3430 | |||
3431 | function CalendarTrust_GetIndexedTrustedPlayers(pTrustSetting, pIndex) |
||
3432 | local vPlayerIndex = 1; |
||
3433 | |||
3434 | for vPlayerName, vPlayerSecurity in gGroupCalendar_PlayerSettings.Security.Player do |
||
3435 | if vPlayerSecurity == pTrustSetting then |
||
3436 | if vPlayerIndex == pIndex then |
||
3437 | return vPlayerName; |
||
3438 | end |
||
3439 | |||
3440 | vPlayerIndex = vPlayerIndex + 1; |
||
3441 | end |
||
3442 | end |
||
3443 | |||
3444 | return nil; |
||
3445 | end |
||
3446 | |||
3447 | function CalendarNetwork_RequestMissingDatabases() |
||
3448 | -- For each player we explicitly trust, see if there's a database for |
||
3449 | -- them yet. If not, request one |
||
3450 | |||
3451 | for vPlayerName, vPlayerSecurity in gGroupCalendar_PlayerSettings.Security.Player do |
||
3452 | if vPlayerSecurity == 1 then |
||
3453 | -- Found a trusted player, see if they have a database |
||
3454 | |||
3455 | local vDatabase = EventDatabase_GetDatabase(vPlayerName, false); |
||
3456 | |||
3457 | if not vDatabase then |
||
3458 | CalendarNetwork_QueueRFURequest(vPlayerName, "DB", 0, 0); |
||
3459 | CalendarNetwork_QueueRFURequest(vPlayerName, "RAT", 0, 0); |
||
3460 | end |
||
3461 | end |
||
3462 | end |
||
3463 | |||
3464 | return nil; |
||
3465 | end |
||
3466 | |||
3467 | function CalendarNetwork_QueueRFURequest(pUserName, pDatabaseTag, pDatabaseID, pRevision) |
||
3468 | if CalendarNetwork_CancelRedundantRFURequest(pDatabaseTag, pUserName, pDatabaseID, pRevision) then |
||
3469 | return; |
||
3470 | end |
||
3471 | |||
3472 | local vRequest = |
||
3473 | { |
||
3474 | mOpcode = pDatabaseTag.."_RFU", |
||
3475 | mUserName = pUserName, |
||
3476 | mDatabaseID = pDatabaseID, |
||
3477 | mRevision = pRevision, |
||
3478 | } |
||
3479 | |||
3480 | CalendarNetwork_QueueRequest(vRequest, gCalendarNetwork_RequestDelay.RFUMin + math.random() * gCalendarNetwork_RequestDelay.RFURange); |
||
3481 | end |
||
3482 | |||
3483 | function CalendarNetwork_PlayerGuildChanged() |
||
3484 | -- Update the guild in the database |
||
3485 | |||
3486 | if gGroupCalendar_UserDatabase then |
||
3487 | gGroupCalendar_UserDatabase.Guild = gGroupCalendar_PlayerGuild; |
||
3488 | end |
||
3489 | |||
3490 | -- Just return if we're not initialized yet |
||
3491 | |||
3492 | if not gGroupCalendar_Initialized then |
||
3493 | EventDatabase_UpdateGuildRankCache(); |
||
3494 | return; |
||
3495 | end |
||
3496 | |||
3497 | -- Clear the roster load flag |
||
3498 | |||
3499 | gGroupCalendar_SentLoadGuildRoster = false; |
||
3500 | |||
3501 | CalendarNetwork_FlushCaches(); |
||
3502 | |||
3503 | -- If the player is unguilded then simply leave the data |
||
3504 | -- channel if it was auto-configured, flush any databases |
||
3505 | -- which are no longer trusted and exit |
||
3506 | |||
3507 | if not IsInGuild() then |
||
3508 | if gGroupCalendar_Settings.DebugInit then |
||
3509 | Calendar_DebugMessage("PlayerGuildChanged: Player is now unguilded"); |
||
3510 | end |
||
3511 | |||
3512 | if gGroupCalendar_PlayerSettings.Channel.AutoConfig then |
||
3513 | CalendarNetwork_LeaveChannel(); |
||
3514 | end |
||
3515 | |||
3516 | EventDatabase_CheckDatabaseTrust(); |
||
3517 | |||
3518 | return; |
||
3519 | end |
||
3520 | |||
3521 | -- The player is in a new guild or has changed guilds, so |
||
3522 | -- schedule a roster update if necessary |
||
3523 | |||
3524 | if GetNumGuildMembers() > 0 then |
||
3525 | if gGroupCalendar_Settings.DebugInit then |
||
3526 | Calendar_DebugMessage("PlayerGuildChanged: Roster is already loaded, calling GuildRosterChanged()"); |
||
3527 | end |
||
3528 | |||
3529 | CalendarNetwork_GuildRosterChanged(); |
||
3530 | end |
||
3531 | |||
3532 | -- Force the roster to reload or to start loading |
||
3533 | |||
3534 | CalendarNetwork_LoadGuildRosterTask(); |
||
3535 | end |
||
3536 | |||
3537 | function CalendarNetwork_GuildRosterChanged() |
||
3538 | if gGroupCalendar_Settings.DebugInit then |
||
3539 | Calendar_DebugMessage("CalendarNetwork_GuildRosterChanged: Checking changes"); |
||
3540 | end |
||
3541 | |||
3542 | EventDatabase_UpdateGuildRankCache(); |
||
3543 | |||
3544 | CalendarNetwork_FlushCaches(); |
||
3545 | |||
3546 | if gGroupCalendar_PlayerSettings.Channel.AutoConfig then |
||
3547 | CalendarNetwork_ScheduleAutoConfig(gCalendarNetwork_RequestDelay.GuildUpdateAutoConfig, true); |
||
3548 | else |
||
3549 | if gGroupCalendar_Settings.DebugInit then |
||
3550 | Calendar_DebugMessage("PlayerGuildChanged: Channel is set for manual config, verifying database trust"); |
||
3551 | end |
||
3552 | |||
3553 | CalendarNetwork_ScheduleCheckDatabaseTrust(5); |
||
3554 | end |
||
3555 | |||
3556 | -- Start sending notices now if we were waiting for a roster update |
||
3557 | |||
3558 | if gGroupCalendar_SendNoticesOnRosterUpdate then |
||
3559 | gGroupCalendar_SendNoticesOnRosterUpdate = nil; |
||
3560 | CalendarNetwork_SendNotices(); |
||
3561 | end |
||
3562 | end |
||
3563 | |||
3564 | function CalendarNetwork_CheckPlayerGuild() |
||
3565 | local vPlayerGuild; |
||
3566 | |||
3567 | if IsInGuild() then |
||
3568 | vPlayerGuild, _, gGroupCalendar_PlayerGuildRank = GetGuildInfo("player"); |
||
3569 | |||
3570 | -- Just return if the server is lagging and the guild info |
||
3571 | -- isn't available yet |
||
3572 | |||
3573 | if not vPlayerGuild then |
||
3574 | return; |
||
3575 | end |
||
3576 | else |
||
3577 | vPlayerGuild = nil; |
||
3578 | gGroupCalendar_PlayerGuildRank = nil; |
||
3579 | end |
||
3580 | |||
3581 | if gGroupCalendar_PlayerGuild ~= vPlayerGuild then |
||
3582 | gGroupCalendar_PlayerGuild = vPlayerGuild; |
||
3583 | |||
3584 | CalendarNetwork_PlayerGuildChanged(); |
||
3585 | end |
||
3586 | end |